def visitStReturn(self, ctx):
     coord = self._ctx_coord(ctx)
     if ctx.ret:
         kid = self.visit(ctx.expr())
     else:
         kid = Ast("VOID", coord=coord)
     return Ast("RETURN", [kid], coord=coord)
 def visitECast(self, ctx):
     coord = self._ctx_coord(ctx)
     typeSpec = self.visit(ctx.typeSpec())
     tName = typeSpec.name
     tRank = typeSpec.rank
     tCoord = typeSpec.coord
     typeCastTo = Ast("TYPE", type_name=tName, rank=tRank, coord=tCoord)
     exprToCast = self.visit(ctx.expr())
     return Ast("CAST", [typeCastTo, exprToCast], coord=coord)
 def visitStIf(self, ctx):
     coord = self._ctx_coord(ctx)
     ifExpr = self.visit(ctx.ifExpr)
     ifStmnt = self.visit(ctx.ifStmnt)
     if ctx.elseStmnt:
         elseStmnt = self.visit(ctx.elseStmnt)
     else:
         elseStmnt = Ast("BLOCK", coord=coord)
     kids = [ifExpr]
     kids.append(ifStmnt)
     kids.append(elseStmnt)
     return Ast("IF", kids, coord=coord)
 def visitEFnCall(self, ctx):
     coord = self._ctx_coord(ctx)
     fnName = self.visit(ctx.expr())
     params = self.visit(ctx.actualParams())
     kids = [fnName]
     kids.extend(params)
     return Ast("APP", kids, coord=coord)
Exemple #5
0
def _make_scope(ast: Ast) -> Environment:
    global_environment = Environment()
    ast.env = global_environment

    def _make_scope_aux(ast: Ast, env: Environment) -> None:
        if isinstance(ast, VarAst):

            def _make_scope_aux_var_ast():
                nonlocal env
                scope = env.lookup(ast.name)
                if scope is None:
                    ast.env = global_environment
                    global_environment.define(ast.name, VarDefine(kind=1))
                else:
                    ast.env = scope
                define: VarDefine = ast.env.get(ast.name)
                define.refs.append(ast)
                ast.define = define

            _make_scope_aux_var_ast()
        if isinstance(ast, LambdaAst):

            def _make_scope_aux_lambda_ast():
                nonlocal env
                ast.env = env = env.extend()
                if ast.name:
                    env.define(ast.name, VarDefine(kind=2))
                for _, param in enumerate(ast.params):
                    env.define(param, VarDefine(kind=2))
                for param in ast.iife_params:
                    env.define(param, VarDefine(kind=3))
                _make_scope_aux(ast.body, env)

            ast = cast(LambdaAst, ast)
            _make_scope_aux_lambda_ast()
        if isinstance(ast, AssignAst):
            _make_scope_aux(ast.left, env)
            _make_scope_aux(ast.right, env)
            if isinstance(ast.left, VarAst):
                ast.left.define.assigned += 1
                ast.left.define.current_value = ast.right
        if isinstance(ast, BinaryAst):
            _make_scope_aux(ast.left, env)
            _make_scope_aux(ast.right, env)

        if isinstance(ast, IfAst):
            _make_scope_aux(ast.cond, env)
            _make_scope_aux(ast.then, env)
            if ast.else_:
                _make_scope_aux(ast.else_, env)
        if isinstance(ast, ProgAst):
            for prog in ast.prog:
                _make_scope_aux(prog, env)
        if isinstance(ast, CallAst):
            _make_scope_aux(ast.func, env)
            for arg in ast.args:
                _make_scope_aux(arg, env)

    _make_scope_aux(ast, global_environment)
    return ast.env
 def visitStWhile(self, ctx):
     coord = self._ctx_coord(ctx)
     expr = self.visit(ctx.expr())
     stmnt = self.visit(ctx.statement())
     kids = [expr]
     kids.append(stmnt)
     return Ast("WHILE", kids, coord=coord)
 def defn(self):
     """Return AST for a defn"""
     defn_coord = self.lookahead.coord
     self.match('FN')
     self.match('PAREN', '(')
     name = self.lookahead.lexeme
     self.match('ID')
     params_coord = self.lookahead.coord
     params = self.params()
     params_ast = Ast('PARAMS',
                      params,
                      coord=params_coord,
                      arity=len(params))
     self.match('PAREN', ')')
     expr = self.expr()
     self.match('SEMI')
     return Ast('DEFN', [params_ast, expr], name=name, coord=defn_coord)
 def visitParams(self, ctx):
     coord = self._ctx_coord(ctx)
     if ctx.formals:
         params = [self.visit(formal) for formal in ctx.formals]
     else:
         params = []
     params += [self.visit(initFormal) for initFormal in ctx.initFormals]
     return Ast('PARAMS', params, coord=coord)
 def visitFnDefinition(self, ctx):
     coord = self._ctx_coord(ctx)
     proto = self.visit(ctx.fnHeader())
     body = self.visit(ctx.block())
     return Ast('DEFN', [proto.returnType, proto.params, body],
                kind=proto.kind,
                isStatic=proto.isStatic,
                name=proto.name,
                coord=coord)
 def visitClassDefinition(self, ctx):
     classBody = self._visit_kids(ctx)
     coord = self._ctx_coord(ctx)
     return Ast('CLASS',
                classBody,
                type_name=ctx.typeName.text,
                super_name="Object"
                if ctx.superName == None else ctx.superName.text,
                coord=coord)
 def visitEAddSub(self, ctx):
     coord = self._ctx_coord(ctx)
     operator = ctx.operator.text
     if operator == "+":
         op = "ADD"
     if operator == "-":
         op = "SUB"
     leftOperand = self.visit(ctx.left)
     rightOperand = self.visit(ctx.right)
     return Ast("OP2", [leftOperand, rightOperand], op=op, coord=coord)
 def visitConstrProto(self, ctx):
     coord = self._ctx_coord(ctx)
     isStatic = True
     name = ctx.TYPE_ID().getText()
     params = self.visit(ctx.params())
     returnType = Ast('TYPE', type_name='$inferred', rank=0, coord=coord)
     return WalnutAstBuilder.Proto(kind='constructor',
                                   isStatic=True,
                                   name=name,
                                   returnType=returnType,
                                   params=params)
 def params(self):
     """Return list of ASTs for formal parameters"""
     if self.look('ID'):
         coord = self.lookahead.coord
         param_ast = Ast('PARAM', name=self.lookahead.lexeme, coord=coord)
         self.match('ID')
         params = self.params()
         params.insert(0, param_ast)
         return params
     else:
         return []
 def visitEMulDivMod(self, ctx):
     coord = self._ctx_coord(ctx)
     operator = ctx.operator.text
     if operator == "*":
         op = "MUL"
     if operator == "/":
         op = "DIV"
     if operator == "%":
         op = "REM"
     leftOperand = self.visit(ctx.left)
     rightOperand = self.visit(ctx.right)
     return Ast("OP2", [leftOperand, rightOperand], op=op, coord=coord)
 def visitVarDec(self, ctx):
     isStatic = ctx.isStatic != None
     kind = ctx.kind.text
     coord = self._ctx_coord(ctx)
     type_name = ""
     rank = 0
     if ctx.typeSp:
         typeInfo = self.visit(ctx.typeSp)
         type_name = typeInfo.name
         rank = typeInfo.rank
     else:
         type_name = "$inferred"
     type_ast = Ast("TYPE", type_name=type_name, rank=rank, coord=coord)
     rest = self._visit_kids(ctx)
     children = [type_ast]
     children.extend(rest)
     return Ast('DECLS',
                children,
                isStatic=isStatic,
                kind=kind,
                coord=coord)
    def expr(self):
        "Return expr AST"
        coord = self.lookahead.coord
        if self.look('INT'):
            value = int(self.lookahead.lexeme)
            self.match('INT')
            return Ast('INT', value=value, coord=coord)
        elif self.look('ID'):
            name = self.lookahead.lexeme
            self.match('ID')
            return Ast('REF', name=name, coord=coord)
        elif self.look('PAREN', '('):
            self.match('PAREN', '(')
            fn_coord = self.lookahead.coord
            name = self.lookahead.lexeme
            if self.look('ID'):
                self.match('ID')
                args_coord = self.lookahead.coord
                args = self.args()
                args_ast = Ast('ARGS', args, coord=args_coord, arity=len(args))
                self.match('PAREN', ')')
                return Ast('APP', [args_ast], name=name, coord=fn_coord)
            elif self.look("LET", "let"):
                self.match('LET')
                idExp_coord = self.lookahead.coord
                idExpList = self.idExp(0)
                idExpList_ast = Ast("LETIDEXPR",
                                    idExpList,
                                    coord=idExp_coord,
                                    arity=(len(idExpList) / 2))
                self.match('IN')
                bodyExp_ast = self.expr()
                self.match("PAREN", ")")
                return Ast('LET', [idExpList_ast, bodyExp_ast], coord=fn_coord)

        elif (self.look('OP')
              and Parser.BINARY_OPS.get(self.lookahead.lexeme, None)):
            op = Parser.BINARY_OPS[self.lookahead.lexeme]
            self.match('OP')
            return Ast(op, [self.expr(), self.expr()], coord=coord)
        elif self.look('OP', '?'):
            self.match('OP')
            return Ast('IF',
                       [self.expr(), self.expr(),
                        self.expr()],
                       coord=coord)
        else:
            raise SyntaxError("Expression expected")
 def visitFnProto(self, ctx):
     isStatic = ctx.isStatic != None
     name = ctx.ID().getText()
     typeSpec = self.visit(ctx.typeSpec())
     tName = typeSpec.name
     tRank = typeSpec.rank
     tCoord = typeSpec.coord
     returnType = Ast("TYPE", type_name=tName, rank=tRank, coord=tCoord)
     params = self.visit(ctx.params())
     return WalnutAstBuilder.Proto(kind='function',
                                   isStatic=isStatic,
                                   name=name,
                                   returnType=returnType,
                                   params=params)
Exemple #18
0
def main(argv=None):
    if argv is None:
        argv = sys.argv

    curWorld.top = Ast(ast.PROGRAM, None)

    if len(argv) > 1:
        for p in argv[1:]:
            if p.endswith(".n"):
                loadFile(p)
            else:
                if loadScript(p) < 0:
                    return 0

    nLoop()
    return 0
 def visitArrConstruction(self, ctx):
     coord = self._ctx_coord(ctx)
     if ctx.prim:
         typeName = ctx.primitiveType().getText()
     else:
         typeName = ctx.TYPE_ID().getText()
     rank = 0
     if ctx.idxs:
         idxs = [self.visit(exp) for exp in ctx.idxs]
         rank = len(ctx.idxs)
     else:
         idxs = []
     return Ast("NEW_ARRAY",
                idxs,
                type_name=typeName,
                rank=rank,
                coord=coord)
 def visitERelation(self, ctx):
     coord = self._ctx_coord(ctx)
     operator = ctx.operator.text
     if operator == "==":
         op = "EQ"
     if operator == "!=":
         op = "NE"
     if operator == "<":
         op = "LT"
     if operator == ">":
         op = "GT"
     if operator == "<=":
         op = "LE"
     if operator == ">=":
         op = "GE"
     leftOperand = self.visit(ctx.left)
     rightOperand = self.visit(ctx.right)
     return Ast("OP2", [leftOperand, rightOperand], op=op, coord=coord)
Exemple #21
0
 def __init__(self, symbol = None):
     ''' Initializes ancestor attributes, and 
     ignore flags.
     '''
     Ast.__init__(self, symbol)