def outAAssignStmt(self, node): '''Manage 'assignment' statement Error Conditions: * rhs id must exist and be a VarDecl or (return type) MethodDecl * lhs and rhs must have equal types''' self.printFunc(self.outAAssignStmt, node) ln = node.getId().getLine() nm = node.getId().getText() decl = G.typeMap().var(self.curClass(), self.curMethod(), nm) if not decl: decl = G.typeMap().glbVar(nm) tp_lhs = Type.NONE tp_rhs = self.typeMap[node.getExpr()] #id does not exist or is not a variable or method if decl == None or not isinstance(decl, (VarDecl, MethodDecl, FuncDecl)): G.errors().semantic().add("'" + nm + "' does not exist", ln) #id exists and is a variable or method elif isinstance(decl, (VarDecl, MethodDecl, FuncDecl)): tp_lhs = G.typeMap().klass(decl.typeName()) #check for equivalent types if decl != None and tp_lhs != tp_rhs: G.errors().semantic().add( "'" + node.toString().strip() + "' assignment requires 2 operands of the same type", ln)
def inAKlassInherits(self, node): '''Manage inheritance Error Conditions: * HACK MiniOodle: inheritance is an unsupported feature''' self.printFunc(self.inAKlassInherits, node) ln = node.getKwFrom().getLine() #get the line number G.errors().semantic().addUnsupportedFeature("'inherits from'", ln)
def outAAssignStmt(self, node): '''Manage 'assignment' statement Error Conditions: * rhs id must exist and be a VarDecl or (return type) MethodDecl * lhs and rhs must have equal types''' self.printFunc(self.outAAssignStmt, node) ln = node.getId().getLine() nm = node.getId().getText() decl = G.typeMap().var(self.curClass(), self.curMethod(), nm) if not decl: decl = G.typeMap().glbVar(nm) tp_lhs = Type.NONE tp_rhs = self.typeMap[node.getExpr()] #id does not exist or is not a variable or method if decl == None or not isinstance(decl, (VarDecl, MethodDecl, FuncDecl)): G.errors().semantic().add("'" + nm + "' does not exist", ln) #id exists and is a variable or method elif isinstance(decl, (VarDecl, MethodDecl, FuncDecl)): tp_lhs = G.typeMap().klass(decl.typeName()) #check for equivalent types if decl != None and tp_lhs != tp_rhs: G.errors().semantic().add("'" + node.toString().strip() + "' assignment requires 2 operands of the same type", ln)
def outAVar(self, node): '''Manage 'var' declarations Error Conditions: * var type is not declared * var type is mismatched''' self.printFunc(self.outAVar, node) err = False #set if error is detected id = node.getId() #TId node nm = id.getText() #variable name ln = id.getLine() #line number #check assignment type tp_assign = Type.NONE if node.getExpr() != None: tp_assign = self.typeMap[node.getExpr()] #check declared type tp_decl = Type.NONE if node.getTp() == None: G.errors().semantic().add("variable '" + nm + "' must have a type", ln) else: tp_decl = self.typeMap[ node.getTp()] #get the variable type from the child node #compare declared and assigned types if tp_assign != Type.NONE and tp_decl != Type.NONE and tp_assign != tp_decl: G.errors().semantic().add( "type mismatch '" + tp_decl.name() + "' := '" + tp_assign.name(), ln) #store this nodes type self.typeMap[node] = tp_decl
def main(): if len(sys.argv) < 2: print "usage:" print " java Oodle filename" return #HACK - add readint() and writeint() declarations G.typeMap().addExtern(ExternDecl('readint', 'int')) G.typeMap().addExtern(ExternDecl('writeint')).addParam(LocalVarDecl('i', 'int')) G.options().parseArgs(sys.argv[1:]) flist = G.fileConcat () for f in G.options().getFileList(): flist.appendFile(f) st_node = None print 'Lexing...' lex = Lexer(flist.getConcatFile().getAbsolutePath()) print 'Parsing...' par = Parser(lex) try: st_node = par.parse() except ParserException, e: G.errors().syntax().add(e.getMessage())
def outAVar(self, node): '''Manage 'var' declarations Error Conditions: * var type is not declared * var type is mismatched''' self.printFunc(self.outAVar, node) err = False #set if error is detected id = node.getId() #TId node nm = id.getText() #variable name ln = id.getLine() #line number #check assignment type tp_assign = Type.NONE if node.getExpr() != None: tp_assign = self.typeMap[node.getExpr()] #check declared type tp_decl = Type.NONE if node.getTp() == None: G.errors().semantic().add("variable '" + nm + "' must have a type", ln) else: tp_decl = self.typeMap[node.getTp()] #get the variable type from the child node #compare declared and assigned types if tp_assign != Type.NONE and tp_decl != Type.NONE and tp_assign != tp_decl: G.errors().semantic().add("type mismatch '" + tp_decl.name() + "' := '" + tp_assign.name(), ln) #store this nodes type self.typeMap[node] = tp_decl
def main(): if len(sys.argv) < 2: print "usage:" print " java Oodle filename" return #HACK - add readint() and writeint() declarations G.typeMap().addExtern(ExternDecl('readint', 'int')) G.typeMap().addExtern(ExternDecl('writeint')).addParam( LocalVarDecl('i', 'int')) G.options().parseArgs(sys.argv[1:]) flist = G.fileConcat() for f in G.options().getFileList(): flist.appendFile(f) st_node = None print 'Lexing...' lex = Lexer(flist.getConcatFile().getAbsolutePath()) print 'Parsing...' par = Parser(lex) try: st_node = par.parse() except ParserException, e: G.errors().syntax().add(e.getMessage())
def inAXtern(self, node): '''''' self.printFunc(self.inAXtern, node) ln = node.getId().getLine() nm = node.getId().getText() tp_map = G.typeMap() if tp_map.externExists(nm): G.errors().semantic().add("extern '" + nm + "' already exists", ln) else: tp_map.addExtern(ExternDecl(nm)) ex = tp_map.extern(nm) if node.getRet(): tp = node.getRet().getTp().getText() ex.setTypeName(tp) #set the return type name args = node.getArgs() for a in args: ln = a.getId().getLine() nm = a.getId().getText() tp = "" if a.getTp(): tp = a.getTp().getTp().getText() if ex.exists(nm): G.errors().semantic().add( "parameter '" + nm + "' already exists", ln) else: par_decl = LocalVarDecl(nm, tp) ex.addParam(par_decl) #add param to TypeMap
def inAXtern(self, node): '''''' self.printFunc(self.inAXtern, node) ln = node.getId().getLine() nm = node.getId().getText() tp_map = G.typeMap() if tp_map.externExists(nm): G.errors().semantic().add("extern '" + nm + "' already exists", ln) else: tp_map.addExtern(ExternDecl(nm)) ex = tp_map.extern(nm) if node.getRet(): tp = node.getRet().getTp().getText() ex.setTypeName(tp) #set the return type name args = node.getArgs() for a in args: ln = a.getId().getLine() nm = a.getId().getText() tp = "" if a.getTp(): tp = a.getTp().getTp().getText() if ex.exists(nm): G.errors().semantic().add("parameter '" + nm + "' already exists", ln) else: par_decl = LocalVarDecl(nm, tp) ex.addParam(par_decl) #add param to TypeMap
def outAArrayExpr(self, node): '''Manage 'array' expression Error Conditions * HACK MiniOodle: me is unsupported''' self.printFunc(self.outAArrayExpr, node) ln = node.getId().getLine() G.errors().semantic().addUnsupportedFeature('array', ln) self.typeMap[node] = Type.NONE
def outAStrExpr(self, node): '''Manage 'string' expr9 expression Error Conditions * HACK MiniOodle: string is unsupported''' self.printFunc(self.outAStrExpr, node) ln = node.getValue().getLine() G.errors().semantic().addUnsupportedFeature("string", ln) self.typeMap[node] = Type.STRING
def outAArrayType(self, node): '''Manage 'array' type Error Conditions: * Unsupported Feature''' self.printFunc(self.outAArrayType, node) ln = node.getLBrack().getLine() G.errors().semantic().addUnsupportedFeature('array', ln) self.typeMap[node] = Type.NONE
def outALoopStmt(self, node): '''Manage 'loop while' statement Error Conditions: * expr type != Type.BOOLEAN''' self.printFunc(self.outALoopStmt) ln = node.getWhile().getLine() tp = self.typeMap[node.getExpr()] if tp != Type.BOOLEAN: G.errors().semantic().add("loops must evaluate on type " + Type.BOOLEAN.name(), ln)
def outALoopStmt(self, node): '''Manage 'loop while' statement Error Conditions: * expr type != Type.BOOLEAN''' self.printFunc(self.outALoopStmt) ln = node.getWhile().getLine() tp = self.typeMap[node.getExpr()] if tp != Type.BOOLEAN: G.errors().semantic().add( "loops must evaluate on type " + Type.BOOLEAN.name(), ln)
def outAFunc(self, node): '''''' self.printFunc(self.outAFunc) vars = node.getVars() #HACK - local variable init is unsupported in MiniOodle sloc = -8 for v in vars: ln = v.getId().getLine() #line number if v.getExpr() != None: G.errors().semantic().addUnsupportedFeature("local variable initialization", ln) self.setCurMethod("")
def inAKlassBody(self, node): '''Manage class variables Error Conditions: * HACK MiniOodle: no class variable initialization''' self.printFunc(self.inAKlassBody) vars = node.getVars() #class variable init is unsupported in MiniOodle for v in vars: if v.getExpr() != None: ln = v.getId().getLine() #line number G.errors().semantic().addUnsupportedFeature("class variable initialization", ln)
def inAFuncArg(self, node): '''''' self.printFunc(self.inAFuncArg, node) ln = node.getId().getLine() tp_map = G.typeMap() func = tp_map.func(self.curMethod()) nm = node.getId().getText() tp = node.getTp().getTp().getText() if func.exists(nm): G.errors().semantic().add("variable '" + nm + "' already exists", ln) else: var_decl = LocalVarDecl(nm, tp) func.addParam(var_decl) #add var to TypeMap
def outAMethod(self, node): '''Manage method leaving a method''' self.printFunc(self.outAMethod) vars = node.getVars() #HACK - local variable init is unsupported in MiniOodle sloc = -8 for v in vars: ln = v.getId().getLine() #line number if v.getExpr() != None: G.errors().semantic().addUnsupportedFeature( "local variable initialization", ln) self.setCurMethod("")
def inAVarToplevel(self, node): '''''' self.printFunc(self.inAVarToplevel, node) ln = node.getVar().getId().getLine() tp_map = G.typeMap() nm = node.getVar().getId().getText() tp = node.getVar().getTp().getTp().getText() if tp_map.glbVarExists(nm): G.errors().semantic().add("global variable '" + nm + "' already exists", ln) else: var_decl = GlobalVarDecl(nm, tp) tp_map.addGlbVar(var_decl) #add var to TypeMap
def inAKlassBody(self, node): '''Manage class variables Error Conditions: * HACK MiniOodle: no class variable initialization''' self.printFunc(self.inAKlassBody) vars = node.getVars() #class variable init is unsupported in MiniOodle for v in vars: if v.getExpr() != None: ln = v.getId().getLine() #line number G.errors().semantic().addUnsupportedFeature( "class variable initialization", ln)
def inAKlassHeader(self, node): '''''' self.printFunc(self.inAKlassHeader, node) ln = node.getId().getLine() tp_map = G.typeMap() nm = node.getId().getText() #class name if tp_map.klassExists(nm): G.errors().semantic().add("class '" + nm + "' already exists", ln) else: tp_map.addKlass(ClassDecl(nm)) #add class to TypeMap self.setCurClass(nm)
def outAPosExpr(self, node): '''Manage 'pos' expression Error Conditions * expression type != Type.INT''' self.printFunc(self.outAPosExpr, node) ln = node.getOp().getLine() tp = self.typeMap[node.getExpr()] tp_ret = Type.INT if tp != Type.INT: tp_ret = Type.NONE G.errors().semantic().add("'" + node.toString().strip() + "' operation requires type " + Type.INT.name(), ln) self.typeMap[node] = tp_ret
def outAPosExpr(self, node): '''Manage 'pos' expression Error Conditions * expression type != Type.INT''' self.printFunc(self.outAPosExpr, node) ln = node.getOp().getLine() tp = self.typeMap[node.getExpr()] tp_ret = Type.INT if tp != Type.INT: tp_ret = Type.NONE G.errors().semantic().add( "'" + node.toString().strip() + "' operation requires type " + Type.INT.name(), ln) self.typeMap[node] = tp_ret
def outANotExpr(self, node): '''Manage 'not' expression Error Conditions * expression type not boolean''' self.printFunc(self.outANotExpr, node) ln = node.getOp().getLine() tp = self.typeMap[node.getExpr()] tp_ret = Type.BOOLEAN if tp != Type.BOOLEAN: tp_ret = Type.NONE G.errors().semantic().add("'" + node.toString().strip() + "' operation requires type " + Type.BOOLEAN.name(), ln) self.typeMap[node] = tp_ret
def inAVarToplevel(self, node): '''''' self.printFunc(self.inAVarToplevel, node) ln = node.getVar().getId().getLine() tp_map = G.typeMap() nm = node.getVar().getId().getText() tp = node.getVar().getTp().getTp().getText() if tp_map.glbVarExists(nm): G.errors().semantic().add( "global variable '" + nm + "' already exists", ln) else: var_decl = GlobalVarDecl(nm, tp) tp_map.addGlbVar(var_decl) #add var to TypeMap
def outANotExpr(self, node): '''Manage 'not' expression Error Conditions * expression type not boolean''' self.printFunc(self.outANotExpr, node) ln = node.getOp().getLine() tp = self.typeMap[node.getExpr()] tp_ret = Type.BOOLEAN if tp != Type.BOOLEAN: tp_ret = Type.NONE G.errors().semantic().add( "'" + node.toString().strip() + "' operation requires type " + Type.BOOLEAN.name(), ln) self.typeMap[node] = tp_ret
def outAUdtType(self, node): '''Manage 'user defined types' (classes types) type Error Conditions:''' self.printFunc(self.outAUdtType, node) err = False nm = node.getTp().getText() ln = node.getTp().getLine() tp = Type.NONE #invalid/undeclared type name if not G.typeMap().klassExists(nm): G.errors().semantic().add("invalid/undeclared type name", ln) else: tp = G.typeMap().klass(nm) self.typeMap[node] = tp
def outAKlass(self, node): '''Manage class declaration Error Conditions: * Mismatched class header and footer names''' self.printFunc(self.outAKlass) err = False nm_hd = node.getKlassHeader().getId().getText() #class header name nm_ft = node.getKlassFooter().getId().getText() #class footer name ln_ft = node.getKlassFooter().getId().getLine() #class footer line number #class names are mismatched if nm_hd != nm_ft: err = True G.errors().semantic().add("mismatched class names 'class " + nm_hd + " is ... end " + nm_ft + "'", ln_ft)
def outAConcatExpr(self, node): '''Manage 'concat' expression Error Conditions * lhs type != Type.STRING and rhs type != Type.STRING''' self.printFunc(self.outAConcatExpr, node) ln = node.getOp().getLine() (lhs, rhs, tp_lhs, tp_rhs) = self.readBinExpr(node) #operand type must be INT tp_ret = self.checkBinExprTypes(node, [Type.STRING]) #incorrect operand types if tp_ret == Type.NONE: G.errors().semantic().add("'" + node.toString().strip() + "' concatenation requires 2 operands of type " + Type.STRING.name(), ln) self.typeMap[node] = tp_ret
def outAKlass(self, node): '''Manage class declaration Error Conditions: * Mismatched class header and footer names''' self.printFunc(self.outAKlass) err = False nm_hd = node.getKlassHeader().getId().getText() #class header name nm_ft = node.getKlassFooter().getId().getText() #class footer name ln_ft = node.getKlassFooter().getId().getLine( ) #class footer line number #class names are mismatched if nm_hd != nm_ft: err = True G.errors().semantic().add( "mismatched class names 'class " + nm_hd + " is ... end " + nm_ft + "'", ln_ft)
def outAOrExpr(self, node): '''Manage 'or' expression Error Conditions * lhs type != Type.BOOLEAN and rhs type != Type.BOOLEAN''' self.printFunc(self.outAOrExpr, node) ln = node.getOp().getLine() (lhs, rhs, tp_lhs, tp_rhs) = self.readBinExpr(node) #operand type must be BOOLEAN tp_ret = self.checkBinExprTypes(node, [Type.BOOLEAN]) #incorrect operand types if tp_ret == Type.NONE: G.errors().semantic().add("'" + node.toString().strip() + "' or-logic requires 2 operands of type " + Type.BOOLEAN.name(), ln) self.typeMap[node] = tp_ret
def inAMethodSig(self, node): '''''' self.printFunc(self.inAMethodSig, node) klass = G.typeMap().klass(self.curClass()) nm = node.getId().getText() if klass.exists(nm): G.errors().semantic().add("method '" + nm + "' already exists", ln) else: klass.addMethod(MethodDecl(nm)) self.setCurMethod(nm) ln = node.getId().getLine() meth = G.typeMap().klass(self.curClass()).method(self.curMethod()) if node.getRet(): tp = node.getRet().getTp().getText() meth.setTypeName(tp) #set the return type name
def outAConcatExpr(self, node): '''Manage 'concat' expression Error Conditions * lhs type != Type.STRING and rhs type != Type.STRING''' self.printFunc(self.outAConcatExpr, node) ln = node.getOp().getLine() (lhs, rhs, tp_lhs, tp_rhs) = self.readBinExpr(node) #operand type must be INT tp_ret = self.checkBinExprTypes(node, [Type.STRING]) #incorrect operand types if tp_ret == Type.NONE: G.errors().semantic().add( "'" + node.toString().strip() + "' concatenation requires 2 operands of type " + Type.STRING.name(), ln) self.typeMap[node] = tp_ret
def outAOrExpr(self, node): '''Manage 'or' expression Error Conditions * lhs type != Type.BOOLEAN and rhs type != Type.BOOLEAN''' self.printFunc(self.outAOrExpr, node) ln = node.getOp().getLine() (lhs, rhs, tp_lhs, tp_rhs) = self.readBinExpr(node) #operand type must be BOOLEAN tp_ret = self.checkBinExprTypes(node, [Type.BOOLEAN]) #incorrect operand types if tp_ret == Type.NONE: G.errors().semantic().add( "'" + node.toString().strip() + "' or-logic requires 2 operands of type " + Type.BOOLEAN.name(), ln) self.typeMap[node] = tp_ret
def inAKlassBody(self, node): '''''' self.printFunc(self.inAKlassBody) klass = G.typeMap().klass(self.curClass()) vars = node.getVars() for v in vars: ln = v.getId().getLine() nm = v.getId().getText() tp = "" if v.getTp(): tp = v.getTp().getTp().getText() if klass.exists(nm): G.errors().semantic().add("variable '" + nm + "' already exists", ln) else: var_decl = InstanceVarDecl(nm, tp) klass.addVar(var_decl) #add var to TypeMap
def outAMethod(self, node): '''''' self.printFunc(self.outAMethod) meth = G.typeMap().klass(self.curClass()).method(self.curMethod()) vars = node.getVars() for v in vars: ln = v.getId().getLine() nm = v.getId().getText() tp = "" if v.getTp(): tp = v.getTp().getTp().getText() if meth.exists(nm): G.errors().semantic().add("variable '" + nm + "' already exists", ln) else: var_decl = LocalVarDecl(nm, tp) meth.addVar(var_decl) #add var to TypeMap self.setCurMethod('')
def outAFunc(self, node): '''''' self.printFunc(self.outAFunc) tp_map = G.typeMap() func = tp_map.func(self.curMethod()) #add all local vars to the TypeMap vars = node.getVars() for v in vars: ln = v.getId().getLine() nm = v.getId().getText() tp = "" if v.getTp(): tp = v.getTp().getTp().getText() if func.exists(nm): G.errors().semantic().add("variable '" + nm + "' already exists", ln) else: var_decl = LocalVarDecl(nm, tp) func.addVar(var_decl) #add var to TypeMap
def inAKlassBody(self, node): '''''' self.printFunc(self.inAKlassBody) klass = G.typeMap().klass(self.curClass()) vars = node.getVars() for v in vars: ln = v.getId().getLine() nm = v.getId().getText() tp = "" if v.getTp(): tp = v.getTp().getTp().getText() if klass.exists(nm): G.errors().semantic().add( "variable '" + nm + "' already exists", ln) else: var_decl = InstanceVarDecl(nm, tp) klass.addVar(var_decl) #add var to TypeMap
def outAMethod(self, node): '''''' self.printFunc(self.outAMethod) meth = G.typeMap().klass(self.curClass()).method(self.curMethod()) vars = node.getVars() for v in vars: ln = v.getId().getLine() nm = v.getId().getText() tp = "" if v.getTp(): tp = v.getTp().getTp().getText() if meth.exists(nm): G.errors().semantic().add( "variable '" + nm + "' already exists", ln) else: var_decl = LocalVarDecl(nm, tp) meth.addVar(var_decl) #add var to TypeMap self.setCurMethod('')
def outAFunc(self, node): '''''' self.printFunc(self.outAFunc) tp_map = G.typeMap() func = tp_map.func(self.curMethod()) #add all local vars to the TypeMap vars = node.getVars() for v in vars: ln = v.getId().getLine() nm = v.getId().getText() tp = "" if v.getTp(): tp = v.getTp().getTp().getText() if func.exists(nm): G.errors().semantic().add( "variable '" + nm + "' already exists", ln) else: var_decl = LocalVarDecl(nm, tp) func.addVar(var_decl) #add var to TypeMap
def inAFuncSig(self, node): '''''' self.printFunc(self.inAFuncSig, node) tp_map = G.typeMap() nm = node.getId().getText() if tp_map.funcExists(nm): G.errors().semantic().add("function '" + nm + "' already exists", ln) else: tp_map.addFunc(FuncDecl(nm)) #FIXME - maybe this should be inside the 'else' clause above self.setCurMethod(nm) ln = node.getId().getLine() func = tp_map.func(self.curMethod()) if node.getRet(): tp = node.getRet().getTp().getText() func.setTypeName(tp) #set the return type name
def outAGtExpr(self, node): '''Manage 'greater than' expression Error Conditions * lhs type != rhs type * lhs_type != (Type.INT | Type.STRING) * rhs_type != (Type.INT | Type.STRING)''' self.printFunc(self.outAGtExpr, node) ln = node.getOp().getLine() (lhs, rhs, tp_lhs, tp_rhs) = self.readBinExpr(node) #operand types must be INT xor STRING tp_ret = self.checkBinExprTypes(node, [Type.INT, Type.STRING]) #incorrect operand types if tp_ret == Type.NONE: G.errors().semantic().add("'" + node.toString().strip() + "' comparison requires 2 operands of type " + Type.INT.name() + " or " + Type.STRING.name(), ln) else: tp_ret = Type.BOOLEAN self.typeMap[node] = tp_ret
def outAIdExpr(self, node): '''Manage 'id' expression Error Conditions * Undefined id * HACK MiniOodle 'out' and 'in' are allowed''' self.printFunc(self.outAIdExpr, node) nm = node.getId().getText() decl = G.typeMap().var(self.curClass(), self.curMethod(), nm) if not decl: decl = G.typeMap().glbVar(nm) ln = node.getId().getLine() tp = Type.NONE #HACK - MiniOodle classes of 'in' and 'out' if nm in ['in', 'out']: pass #id is undefined elif decl == None: G.errors().semantic().add("undefined variable '" + nm + "'", ln) else: tp = G.typeMap().klass(decl.typeName()) self.typeMap[node] = tp #assign this nodes type
def outAGtExpr(self, node): '''Manage 'greater than' expression Error Conditions * lhs type != rhs type * lhs_type != (Type.INT | Type.STRING) * rhs_type != (Type.INT | Type.STRING)''' self.printFunc(self.outAGtExpr, node) ln = node.getOp().getLine() (lhs, rhs, tp_lhs, tp_rhs) = self.readBinExpr(node) #operand types must be INT xor STRING tp_ret = self.checkBinExprTypes(node, [Type.INT, Type.STRING]) #incorrect operand types if tp_ret == Type.NONE: G.errors().semantic().add( "'" + node.toString().strip() + "' comparison requires 2 operands of type " + Type.INT.name() + " or " + Type.STRING.name(), ln) else: tp_ret = Type.BOOLEAN self.typeMap[node] = tp_ret
def outACall(self, node): '''Manage a method 'call' Error Conditions * object does not contain method id * method id does not exist in 'me' * wrong number of parameters * wrong parameter types''' self.printFunc(self.outACall, node) tp_map = G.typeMap() ln = node.getId().getLine() nm = node.getId().getText() klass = None if node.getExpr(): klass = self.typeMap[node.getExpr()] if klass: klass = klass.typeName() else: klass = self.curClass() decl = G.typeMap().method( klass, nm) #FIXME - only allows calls to methods within the same class if not decl: decl = G.typeMap().func(nm) if not decl: decl = G.typeMap().extern(nm) ls_args = [self.typeMap[a] for a in node.getArgs()] tp_ret = Type.NONE #id does not exist or is not a method id if decl == None or not isinstance(decl, (MethodDecl, ExternDecl, FuncDecl)): G.errors().semantic().add("method '" + nm + "' does not exist", ln) #check for correct number and type of parameters elif len(ls_args) > 0: params = [tp_map.klass(p.typeName()) for p in decl.params()] if len(params) != len(ls_args): G.errors().semantic().add( "method '" + nm + "' expects " + str(len(params)) + " parameter(s) but was given " + str(len(ls_args)), ln) elif ls_args != params: G.errors().semantic().add( "method '" + nm + "' expects parameters " + str([str(p) for p in params]) + " but was given " + str([str(a) for a in ls_args]), ln) #get method return type if decl != None: tp_ret = G.typeMap().klass(decl.typeName()) self.typeMap[node] = tp_ret
def outACall(self, node): '''Manage a method 'call' Error Conditions * object does not contain method id * method id does not exist in 'me' * wrong number of parameters * wrong parameter types''' self.printFunc(self.outACall, node) tp_map = G.typeMap() ln = node.getId().getLine() nm = node.getId().getText() klass = None if node.getExpr(): klass = self.typeMap[node.getExpr()] if klass: klass = klass.typeName() else: klass = self.curClass() decl = G.typeMap().method(klass, nm) #FIXME - only allows calls to methods within the same class if not decl: decl = G.typeMap().func(nm) if not decl: decl = G.typeMap().extern(nm) ls_args = [self.typeMap[a] for a in node.getArgs()] tp_ret = Type.NONE #id does not exist or is not a method id if decl == None or not isinstance(decl, (MethodDecl, ExternDecl, FuncDecl)): G.errors().semantic().add("method '" + nm + "' does not exist", ln) #check for correct number and type of parameters elif len(ls_args) > 0: params = [tp_map.klass(p.typeName()) for p in decl.params()] if len(params) != len(ls_args): G.errors().semantic().add("method '" + nm + "' expects " + str(len(params)) + " parameter(s) but was given " + str(len(ls_args)), ln) elif ls_args != params: G.errors().semantic().add("method '" + nm + "' expects parameters " + str([str(p) for p in params]) + " but was given " + str([str(a) for a in ls_args]), ln) #get method return type if decl != None: tp_ret = G.typeMap().klass(decl.typeName()) self.typeMap[node] = tp_ret
for f in G.options().getFileList(): flist.appendFile(f) st_node = None print 'Lexing...' lex = Lexer(flist.getConcatFile().getAbsolutePath()) print 'Parsing...' par = Parser(lex) try: st_node = par.parse() except ParserException, e: G.errors().syntax().add(e.getMessage()) except LexerException, f: print "LexerException in Oodle.__init__" if G.errors().hasErrors(): G.errors().printErrors() return #Pass 1 #build the TypeMap for all the input print 'Building Type Map...' tp_map_builder = TypeMapBuilder() st_node.apply(tp_map_builder) #invoke TypeMapBuilder traversal #Pass 2 #perform semantic checks (new code) print 'Error Checking...' sem_check = SemanticChecker() st_node.apply(sem_check) #invoke SemanticChecker traversal
def printError(self, tok_name, txt=None): '''Print error messages and also add it to the Lex error log @tok_name: token name @txt: custom token text''' msg = self.printMsg(tok_name, txt) G.errors().lex().add(msg)
def outAStringType(self, node): '''Unsupported Feature for MiniOodle''' self.printFunc(self.outAStringType, node) self.typeMap[node] = Type.STRING #store this nodes type ln = node.getTp().getLine() #get the line number G.errors().semantic().addUnsupportedFeature('string', ln)