KLL Compiler
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

kll.py 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #!/usr/bin/env python3
  2. '''
  3. Re-Emits KLL files after processing. May do simplification.
  4. '''
  5. # Copyright (C) 2016 by Jacob Alexander
  6. #
  7. # This file is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This file is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this file. If not, see <http://www.gnu.org/licenses/>.
  19. ### Imports ###
  20. import os
  21. from common.emitter import Emitter, FileEmitter
  22. ### Decorators ###
  23. ## Print Decorator Variables
  24. ERROR = '\033[5;1;31mERROR\033[0m:'
  25. WARNING = '\033[5;1;33mWARNING\033[0m:'
  26. ### Classes ###
  27. class KLL( Emitter, FileEmitter ):
  28. '''
  29. Re-Emits KLL files, may simplify and re-order expressions.
  30. '''
  31. def __init__( self, control ):
  32. '''
  33. Emitter initialization
  34. @param control: ControlStage object, used to access data from other stages
  35. '''
  36. Emitter.__init__( self, control )
  37. FileEmitter.__init__( self )
  38. # Defaults
  39. self.target_dir = "generated"
  40. def command_line_args( self, args ):
  41. '''
  42. Group parser for command line arguments
  43. @param args: Name space of processed arguments
  44. '''
  45. self.target_dir = args.target_dir
  46. def command_line_flags( self, parser ):
  47. '''
  48. Group parser for command line options
  49. @param parser: argparse setup object
  50. '''
  51. # Create new option group
  52. group = parser.add_argument_group('\033[1mKLL Emitter Configuration\033[0m')
  53. group.add_argument( '--target-dir', type=str, default=self.target_dir,
  54. help="Target directory for generated files.\n"
  55. "\033[1mDefault\033[0m: {0}\n".format( self.target_dir )
  56. )
  57. def output( self ):
  58. '''
  59. Final Stage of Emitter
  60. Generate KLL files
  61. '''
  62. # Make sure output directory exists
  63. os.makedirs( self.target_dir, exist_ok=True )
  64. # Output list of files to disk
  65. self.generate( self.target_dir )
  66. def reconstitute_store( self, stores, name, debug=False ):
  67. '''
  68. Takes a list of organization stores and re-constitutes them into a kll file
  69. @param stores: List of organization stores
  70. @param name: Filename to call list of stores
  71. @param debug: Debug mode (adds a comment to every line with the store key)
  72. @return: kll file contents
  73. '''
  74. output = ""
  75. for store in stores:
  76. for key, value in sorted( store.data.items(), key=lambda x: x[0] ):
  77. if debug:
  78. output += "{0} # {1}\n".format( value, key )
  79. else:
  80. output += "{0}\n".format( value )
  81. self.output_files.append( (name, output) )
  82. def process( self ):
  83. '''
  84. Emitter Processing
  85. Takes KLL datastructures and Analysis results then outputs them individually as kll files
  86. '''
  87. # Acquire Datastructures
  88. early_contexts = self.control.stage('DataOrganizationStage').contexts
  89. base_context = self.control.stage('DataFinalizationStage').base_context
  90. default_context = self.control.stage('DataFinalizationStage').default_context
  91. partial_contexts = self.control.stage('DataFinalizationStage').partial_contexts
  92. full_context = self.control.stage('DataFinalizationStage').full_context
  93. # Re-constitute KLL files using contexts of various stages
  94. for key, context in early_contexts.items():
  95. self.reconstitute_store( context.organization.stores(), "{0}.kll".format( key ) )
  96. self.reconstitute_store( base_context.organization.stores(), "base.kll" )
  97. self.reconstitute_store( default_context.organization.stores(), "default.kll" )
  98. for index, partial in enumerate( partial_contexts ):
  99. self.reconstitute_store( partial.organization.stores(), "partial-{0}.kll".format( index ) )
  100. self.reconstitute_store( full_context.organization.stores(), "final.kll" )