Пример #1
0
 def static_init_app_ast(self, name):
     """Generate an APP to call static initializer for class name"""
     accessAst = Ast('STATIC_ACCESS', [],
                     type_name=name,
                     name=constants.STATIC_INIT,
                     coord=sys_coord())
     app_ast = Ast('APP', [accessAst], coord=sys_coord())
     return app_ast
Пример #2
0
 def default_constructor_ast(self):
     return (Ast('DEFN', [
         Ast('TYPE', coord=sys_coord(), type_name=self.class_name, rank=0),
         Ast('PARAMS', [], coord=sys_coord()),
         Ast('BLOCK', [], coord=sys_coord())
     ],
                 name=self.class_name,
                 kind='constructor',
                 isStatic=True,
                 coord=sys_coord()))
Пример #3
0
 def ensure_super(self, ast):
     assert (ast.tag == 'DEFN' and ast.kind == 'constructor')
     block = ast.kids[2]
     needs_super = (len(block.kids) == 0 or block.kids[0].tag != 'APP'
                    or block.kids[0].kids[0].tag != 'ID'
                    or block.kids[0].kids[0].name != 'super')
     if needs_super:
         super_call = (Ast('APP',
                           [Ast('ID', [], name='super', coord=sys_coord())],
                           coord=sys_coord()))
         block.kids.insert(0, super_call)
     return ast
Пример #4
0
 def make_main(self, splits):
     code = [self.static_init_app_ast(constants.MAIN_CLASS)]
     for ast in splits.classes:
         assert (ast.tag == 'CLASS')
         code.append(self.static_init_app_ast(ast.type_name))
     code += splits.static_decls
     ret_type = Ast('TYPE', [], type_name='Void', rank=0, coord=sys_coord())
     params = Ast('PARAMS', [], coord=sys_coord())
     block = Ast('BLOCK', code + splits.stmts, coord=sys_coord())
     return Ast('DEFN', [ret_type, params, block],
                isStatic=True,
                kind='function',
                name=constants.MAIN_FN,
                coord=sys_coord())
Пример #5
0
 def malloc(self):
     assert (len(self.constr_asts) == 1)
     constr = self.constr_asts[0]
     assert (constr.tag == 'DEFN')
     assert (constr.kind == 'constructor')
     name = self.class_name
     constr_params = constr.kids[1]
     assert (constr_params.tag == 'PARAMS')
     actuals = [
         Ast('ID', name=param.name, coord=sys_coord())
         for param in constr_params.kids
     ]
     self_ref = Ast('ID', name='self', coord=sys_coord())
     access_ast = Ast('ACCESS', [self_ref],
                      coord=sys_coord(),
                      name=self.klass.instance_init_name())
     app_ast = Ast('APP', [access_ast] + actuals, coord=sys_coord())
     type_id = Ast('TYPE_ID', type_name=name, rank=0, coord=sys_coord())
     template = Constructor.MALLOC_BLOCK_TEMPLATE.replace('$C', name)
     template_dict = {
         "$typeId": type_id,
         "$initCall": app_ast,
     }
     block = Template.substitute('block', template, template_dict)
     ret_type = Ast('TYPE', type_name=name, rank=0, coord=sys_coord())
     params = copy.deepcopy(constr_params)
     ast = Ast('DEFN', [ret_type, params, block],
               name=name,
               kind='function',
               isStatic=True,
               coord=sys_coord())
     return ast
Пример #6
0
 def instance_init(self):
     """return copy of constr_asts[0] with name changed to SELF_INIT and
        kind set to function
     """
     assert (len(self.constr_asts) == 1)
     constr = self.constr_asts[0]
     assert (constr.tag == 'DEFN')
     assert (constr.kind == 'constructor')
     init = copy.deepcopy(constr)
     init.name = self.klass.instance_init_name()
     init.kind = 'function'
     init.isStatic = False
     self_ast = Ast('ID', name='self', coord=sys_coord())
     return_ast = Ast('RETURN', [self_ast], coord=sys_coord())
     block = init.kids[2]
     assert (block.tag == 'BLOCK')
     block.kids.append(return_ast)
     return init
Пример #7
0
 def xform_super(self, constr):
     """take super(...) call in constr (by the time it is called,
        it must have one) and replace it with super.INSTANCE_INIT(...)
     """
     assert (constr.tag == 'DEFN' and constr.kind == 'constructor')
     super_klass = checker.types.get(self.klass.parent)
     assert (super_klass)
     block = constr.kids[2]
     super_call = block.kids[0]
     assert (super_call.tag == 'APP')
     assert (super_call.kids[0].tag == 'ID')
     assert (super_call.kids[0].name == 'super')
     if super_klass.name != constants.OBJECT:
         super_id = Ast('ID', name='super', coord=sys_coord())
         super_init_name = super_klass.instance_init_name()
         access = Ast('ACCESS', [super_id],
                      name=super_init_name,
                      coord=sys_coord())
         params = [access] + copy.deepcopy(super_call.kids[1:])
         block.kids[0] = Ast('APP', params, coord=sys_coord())
     else:
         block.kids.pop(0)  #excise super call as super is Object
Пример #8
0
 def substitute(non_terminal, template, template_dict):
     """return ast corresponding to the walnut source code template parsed
         as non_terminal with all occurrences of the $KEY replaced
         by the precomputed ast from template_dict[KEY]
     """
     #set up artificial source path to indicate caller's location
     path = str(sys_coord(2))
     n_errors, ast = parse_string(path, template, non_terminal,
                                  template_dict)
     if n_errors > 0:
         sys.stderr.write('INTERNAL ERROR: template parse has %d errors' %
                          n_errors)
     return ast
Пример #9
0
 def __init__(self, splits):
     super().__init__(constants.MAIN_CLASS, constants.OBJECT, sys_coord(),
                      splits)
     main_ast = self.make_main(splits)
     splits.fns.append(main_ast)
Пример #10
0
 def __init__(self, element_type, rank):
     super().__init__(element_type, 'Array', sys_coord(),
                      Splits(Ast('CLASS', [])), rank)
     assert(rank > 0)
Пример #11
0
 def __init__(self):
     super().__init__(constants.NIL_TYPE, 'nil')
     self.type = self
     self.coord = sys_coord()
Пример #12
0
 def __init__(self, name):
     super().__init__(name, 'primitive')
     self.type = self
     self.coord = sys_coord()
Пример #13
0
from splits import Splits
from walnutsys import sys_coord
from util import is_multi_def
from toptypes import TopTypes
from type import NilType, PrimitiveType

# top-level of semantic checker which provides behavior
# (note that checker simply provides a global variable to
# access important data-structures like types, without any
# interesting behavior; all behavior is implemented here).

PREDEF_CLASSES = [
    Ast('CLASS', [],
        type_name=constants.OBJECT,
        super_name=None,
        coord=sys_coord()),
    #Ast('CLASS', [], type_name='System', super_name=None, coord=sys_coord()),
]

PREDEF_TYPES = [
    'Int',
    'Real',
    'String',
    'Void',
]


class SemanticChecker:
    def __init__(self):
        checker.types = TopTypes()
        checker.errors = Errors()