def resolveClass(node: Node, parentScope: Scope): for child in node.getChildNodes(): if child.nodeType == NodeType.CLASS: name = child.getChild('name') type_ = Type(name, True) symbol = Symbol(name, type_, SymbolKind.CLASS) child.symbol = symbol child.resolvedType = type_ parentScope.define(symbol) scope = Scope(parentScope) scope.classType = type_ child.scope = scope
def resolveAssign(parentScope: Scope, target: Node, type_: Type, addVar=True): target.parentScope = parentScope target.resolvedType = type_ if target.nodeType == NodeType.NAME: name = target.getText() symbol = parentScope.findNested(name) if not symbol: symbol = Symbol(name, type_) parentScope.define(symbol) target.symbol = symbol elif target.nodeType == NodeType.TUPLE: elts = target.getChild('elts') for i, elt in enumerate(elts): resolveAssign(parentScope, elt, type_.elementTypes[i], addVar) elif target.nodeType == NodeType.ATTR: var_name = target.getChild('value').getText() var_attr = target.getChild('attr') tmp = target while tmp != None and tmp.nodeType != NodeType.FUNCTION: tmp = tmp.parent if tmp and tmp.getChild('name') == '__init__': args = tmp.getChild('args').getChild('args') if args and args[0].getChild('arg') == var_name: classType = tmp.parentScope.classType classType.addField(var_attr, type_) elif target.nodeType == NodeType.SUBSCRIPT: pass else: raise Exception('Unknown node type:' + target.nodeType)
interpolate = False elif arg.type == "word" and arg.value == "\\": escaped = True elif arg.type == "word" and arg.value == "&": interpolate = True elif arg.type == "tuple": new_args.append(tuple_mutator(scope, arg)) else: new_args.append(arg) return ASTTuple(new_args) def template_ast(scope, args): assert len(args) == 1, f"ast expects 1 arg, {len(args)} given" ast = args[0] assert ast.type == "tuple", f"ast expects first arg to be a tuple" return ASTTemplate(tuple_mutator(scope, ast)) template_scope = Scope() template_scope.add_natives(NATIVES) template_scope.define("ast", template_ast) def parse_template(template_ast): sub_scope = Scope(parent=template_scope) return sub_scope.execute_statement(template_ast)
if save_type.value == "as": save_type = MacroMatch.AS else: save_type = MacroMatch.INTO save_name = save_name.value return ReadPattern(pattern=pattern, flags=flags, save_type=save_type, save_name=save_name) def sequence_pattern(scope, args): return SequencePattern([parse_pattern(arg) for arg in args]) pattern_scope = Scope() pattern_scope.define("token", token_pattern) pattern_scope.define("ast", ast_pattern) pattern_scope.define("read", read_pattern) pattern_scope.define("seq", sequence_pattern) def parse_pattern(pattern_ast): if pattern_ast.type == "word": return TokenPattern(content=pattern_ast.value) return pattern_scope.execute_statement(pattern_ast)
def resolve(node: Node, parentScope: Scope): nodeType = node.nodeType node.parentScope = parentScope resolveClass(node, parentScope) resolveFunction(node, parentScope) if nodeType in [NodeType.FUNCTION, NodeType.CLASS]: parentScope = node.scope if not node.resolvedType: if nodeType in [NodeType.ASSIGN, NodeType.ANN_ASSIGN]: value = node.getChild('value') resolve(value, parentScope) type_ = value.resolvedType if node.getChild('annotation'): annotation = node.getChild('annotation') type_ = getAnnotationType(parentScope, annotation) if nodeType == NodeType.ASSIGN: targets = node.getChild('targets') else: targets = [node.getChild('target')] for target in targets: resolveAssign(parentScope, target, type_) elif node.isExpression(): node.resolvedType = getExpressionType(node) elif nodeType == NodeType.WHILE: scope = Scope(parentScope) scope.isLoop = True parentScope = node.scope = scope elif nodeType in [NodeType.FOR, NodeType.COMP]: scope = Scope(parentScope) scope.isLoop = nodeType == NodeType.FOR parentScope = node.scope = scope target = node.getChild('target') iter_ = node.getChild('iter') resolve(iter_, parentScope) type_ = iter_.resolvedType resolveAssign(parentScope, target, type_.elementTypes[0], addVar=False) elif nodeType == NodeType.BLOCK: if node.parent.nodeType not in [ NodeType.CLASS, NodeType.FUNCTION, NodeType.FOR, NodeType.WHILE ]: scope = Scope(parentScope) parentScope = node.scope = scope else: parentScope = node.scope = node.parent.scope elif nodeType == NodeType.ARGUMENTS: args = node.getChild('args') for i, arg in enumerate(args): arg.parentScope = parentScope type_ = getArgumentType(arg, i) name = arg.getChild('arg') symbol = Symbol(name, type_) arg.resolvedType = type_ parentScope.define(symbol) for child_node in node.getChildNodes(): resolve(child_node, parentScope)