def generics(parser, fname): generic = coll.OrderedDict() while parser.thisToken().token != "]": name = parser.nextToken().token typ = Types.T(name, Types.All, parser.package+"."+fname) if parser.thisToken().type != "identifier": Error.parseError(parser, "type name must be an identifier") if not parser.nextToken().token in [":", ",", "]"]: Error.parseError(parser, "expecting ,") if parser.thisToken().token == ":": parser.nextToken() typ = Types.T(name, Types.parseType(parser), parser.package+"."+fname) if parser.lookInfront().token != "]": parser.nextToken() Scope.addVar(Tree.PlaceHolder(parser), parser, name, Scope.Type(False, typ)) generic[name] = typ if parser.lookInfront().token == "]": parser.nextToken() break parser.nextToken() return generic
def index(parser, unary=False): if not unary: unary = ExprParser.isUnary(parser, parser.lookBehind()) if not unary and len(parser.currentNode.nodes) == 0: Error.parseError(parser, "unexpected .") field = parser.nextToken() if not field.type in ["identifier", "i32"]: Error.parseError(parser, "field name must be an identifier") acess = Tree.Field(0, Types.Null(), parser) acess.unary = unary acess.number = field.type == "i32" field = field.token acess.owner = parser.currentNode acess.field = field if not unary: acess.addNode(parser.currentNode.nodes[-1]) parser.currentNode.nodes[-1] = acess else: parser.currentNode.addNode(acess)
def _packDec(parser, pack=False): name = parser.nextToken() if name.type != "identifier": Error.parseError(parser, "package name must be an identifier") name = name.token packDec(parser, name, pack)
def elseExpr(parser): toplevel = Tree.Else(parser) try: inside = parser.currentNode.nodes[-1].nodes[-2] except IndexError: Error.parseError(parser, "unexpected else") if not type(inside) is Tree.IfCondition: Error.parseError(parser, "unexpected else") parser.currentNode.nodes[-1].addNode(toplevel) parser.currentNode = toplevel block = Tree.Block(parser) parser.currentNode.owner.addNode(block) parser.currentNode = block opening = None single = 0 while not Parser.isEnd(parser): token = parser.nextToken() Parser.callToken(parser) ExprParser.endExpr(parser) parser.currentNode = toplevel.owner.owner
def aliasParser(parser, name, decl, generic): parser.nextToken() typ = False while not Parser.isEnd(parser): if parser.thisToken().token != "\n" and parser.thisToken().type != "indent": if typ: Error.parseError(parser, "Unexpected token " + parser.thisToken().token) typ = Types.parseType(parser) parser.nextToken() if decl: alias = parser.interfaces[parser.package][name] tmp = Types.Alias(parser.package, name, typ, generic) alias.name = tmp.name alias.normalName = tmp.normalName alias.typ = tmp.typ alias.generic = tmp.generic alias.remainingGen = tmp.remainingGen alias.types = tmp.types alias.methods = tmp.methods if decl: parser.interfaces[parser.package][name] = alias Scope.decrScope(parser)
def pattern(name, names, parser, getName): if type(name) is Tree.Tuple: for i in name: pattern(i, names, parser, getName) return name elif type(name) is Tree.PlaceHolder: node = name.nodes[0] pattern(node, names, parser, getName) elif type(name) is Tree.InitStruct: for i in name: if type(i) is Tree.Assign: if not type(i.nodes[0]) is Tree.ReadVar: i.error("Expecting variable name") pattern(i.nodes[1], names, parser, getName) elif type(i) is Tree.ReadVar: pattern(i, names, parser, getName) else: i.error("Expecting variable name") return name elif type(name) is Tree.ReadVar: names.append(name.name) return getName(name.token) elif type(name) is Tree.Under: names.append(name.name) elif type(name) is Lexer.Token and name.type == "identifier": return getName(name) else: if type(name) is Lexer.Token: if name.type == "indent": Error.parseError(parser, "Expecting identifier") else: Error.parseError(parser, "Unexpected token " + name.token) else: name.error("Unexpected token")
def genericT(parser): parser.nextToken() if len(parser.currentNode.nodes) > 0: func = parser.currentNode.nodes.pop() else: Error.parseError(parser, "unexpected ::") generic = Tree.Generic(parser) parser.currentNode.addNode(generic) generic.addNode(func) generic.generic = [] if parser.thisToken().token != "[": Error.parseError(parser, "expecting [") parser.nextToken() while parser.thisToken().token != "]": if parser.thisToken().token == ",": parser.nextToken() parser.nodeBookmark[-1] = len(parser.currentNode.nodes) continue generic.generic.append(Types.parseType(parser)) t = parser.thisToken().token parser.nextToken()
def _packDec(parser, pack= False): name = parser.nextToken() if name.type != "identifier": Error.parseError(parser, "package name must be an identifier") name = name.token packDec(parser, name, pack)
def createParser(parser, name="", typ=None, check=True, imutable=True, attachTyp=False): # : creation if name == "": name = parser.lookBehind() if name.type != "identifier": Error.parseError( parser, "variable name must be of type identifier, not " + parser.lookBehind().type) name = name.token if name[0].lower() != name[0]: Error.parseError(parser, "variable name must be lower case") node = Tree.Create(name, Types.Null(), parser) node.package = parser.package node.imutable = imutable if attachTyp: node.attachTyp = attachTyp parser.currentNode.addNode(node) node.varType = typ if check and typ is None: parser.nextToken() typ = Types.parseType(parser) node.varType = typ
def forExpr(parser): toplevel = Tree.For(parser) parser.currentNode.addNode(toplevel) parser.currentNode = toplevel while not (Parser.isEnd(parser) or parser.thisToken().token == "do"): token = parser.nextToken() if token.token == "do": break Parser.callToken(parser) ExprParser.endExpr(parser) parser.nodeBookmark.append(len(parser.currentNode.nodes)) if parser.thisToken().token != "do": Error.parseError(parser, "Expecting do") if len(toplevel.nodes) != 1: #or not type(toplevel.nodes[0]) is Tree.CreateAssign: Error.parseError(parser, "Expecting single node") count = 0 while not (Parser.isEnd(parser) and count > 0): #avoid breaking on do keyword count += 1 token = parser.nextToken() Parser.callToken(parser) parser.nodeBookmark.pop() parser.currentNode = toplevel.owner
def createParser(parser, name= "", typ= None, check= True, imutable= True, attachTyp= False): # : creation if name == "": name = parser.lookBehind() if name.type != "identifier": Error.parseError(parser, "variable name must be of type identifier, not "+parser.lookBehind().type) name = name.token if name[0].lower() != name[0]: Error.parseError(parser, "variable name must be lower case") node = Tree.Create(name, Types.Null(), parser) node.package = parser.package node.imutable = imutable if attachTyp: node.attachTyp = attachTyp parser.currentNode.addNode(node) node.varType = typ if check and typ is None: parser.nextToken() typ = Types.parseType(parser) node.varType = typ
def addMethod(self, parser, name, method): package = parser.package if package in self.methods: if name in parser.structs[package][self.name].methods[package]: Error.parseError(parser, "method "+self.name+"."+name+" already exists") self.methods[package][name] = method else: self.methods[package] = {name: method}
def enumParser(parser, name, decl, generic): const = parser.interfaces[parser.package][name].const existing_generics = parser.interfaces[parser.package][name].generic existing_generics.update(generic) #const = coll.OrderedDict() enum = Types.Enum(parser.package, name, const, existing_generics) if decl: parser.interfaces[parser.package][name] = enum """if parser.lookInfront().token == "\n": parser.nextToken() Parser.callToken(parser) parser.nextToken()"" \ """ while not Parser.isEnd(parser): t = parser.nextToken() if t.token == "\n" or t.type == "indent": Parser.callToken(parser) continue if t.type != "identifier": Error.parseError(parser, "expecting identifier") varName = t.token if varName[0].upper() != varName[0]: Error.parseError(parser, "constructor type must be capitalized") args = [] nextT = parser.nextToken() #print(varName) #print(nextT) if nextT.token == "(": args = Types.parseType(parser).list const[varName] = args if decl: Scope.addVar(Tree.PlaceHolder(parser), parser, varName, Scope.Type( True, Types.FuncPointer(args, enum, generic=generic) if len(args) > 0 else enum), _global=True) t = parser.thisToken() if t.token == "\n" or t.type == "indent": Parser.callToken(parser) parser.currentNode.addNode(Tree.Enum(const, name, parser, generic)) Scope.decrScope(parser)
def getName(name): if name.type != "identifier": Error.parseError(parser, "variable name must be of type identifier, not " + parser.lookBehind().type) name = name.token if name[0].lower() != name[0]: Error.parseError(parser, "variable name must be lower case") return name
def asOperator(parser): lastToken = parser.lookBehind() if not isUnary(parser, lastToken): op = Tree.Operator("as", parser) parser.nextToken() op.type = Types.parseType(parser) Parser.Opcode(parser, "as", lambda: operatorPop(parser, op, 1, unary=True)) else: Error.parseError(parser, "unexpected as operator ")
def f(parser): op = Tree.Operator(kind, parser) if kind != "|>" and len(parser.currentNode.nodes) != 0: if not unary and isUnary(parser, parser.lookBehind()): Error.parseError(parser, "unexpected "+kind) elif unary and not isUnary(parser, parser.lookBehind()): Error.parseError(parser, "unexpected "+kind) #parser.nodeBookmark.append(len(parser.currentNode.nodes)-1) Parser.Opcode(parser, kind, lambda: operatorPop(parser, op, takesIn, unary))
def elifExpr(parser): try: inside = parser.currentNode.nodes[-1].nodes[-2] except IndexError: Error.parseError(parser, "unexpected elif") if not type(inside) is Tree.IfCondition: Error.parseError(parser, "unexpected elif") parser.currentNode = parser.currentNode.nodes[-1] ifBody(parser)
def castParser(parser): if len(parser.currentNode.nodes) == 0: Error.parseError(parser, "Unexpected cast") parser.nextToken() node = Tree.CastToType(parser) node.type = Types.parseType(parser) node.addNode(parser.currentNode.nodes[-1]) parser.currentNode.nodes[-1] = node node.owner = parser.currentNode
def f(parser): op = Tree.Operator(kind, parser) actuallyUnary = isUnary(parser, parser.lookBehind()) if len(parser.currentNode.nodes) != 0: if not unary and actuallyUnary: Error.parseError(parser, "unexpected "+kind) elif unary and not actuallyUnary: Error.parseError(parser, "unexpected "+kind) #parser.nodeBookmark.append(len(parser.currentNode.nodes)-1) Parser.Opcode(parser, kind, lambda: operatorPop(parser, op, takesIn, actuallyUnary))
def elseExpr(parser, canHaveElse=False): toplevel = Tree.Else(parser) ifexpr = False if not canHaveElse: try: inside = parser.currentNode.nodes[-1].nodes[-2] except IndexError: Error.parseError(parser, "unexpected else") if not type(inside) is Tree.IfCondition: ifexpr = IfExpr.ifPatternMatch(parser) if not ifexpr: Error.parseError(parser, "unexpected else") if not ifexpr: parser.currentNode.nodes[-1].addNode(toplevel) parser.currentNode = toplevel block = Tree.Block(parser) parser.currentNode.owner.addNode(block) parser.currentNode = block else: parser.currentNode = parser.currentNode.nodes[-1].nodes[-1] while len(parser.currentNode.nodes) > 0: parser.currentNode = parser.currentNode.nodes[-1] add_block = len(parser.currentNode.nodes) > 0 if add_block: block = Tree.Block(parser) parser.currentNode.nodes[-1].addNode(toplevel) parser.currentNode.nodes[-1].addNode(block) parser.currentNode = parser.currentNode.nodes[-1] parser.currentNode = block opening = None single = 0 while not Parser.isEnd(parser): token = parser.nextToken() Parser.callToken(parser) ExprParser.endExpr(parser) if ifexpr: parser.currentNode = ifexpr else: parser.currentNode = toplevel.owner.owner
def traitParser(parser, name, decl, generic): interface = parser.interfaces[parser.package][name] meth = {} while not Parser.isEnd(parser): parser.nextToken() t = parser.thisToken() if t.token == "def": currentNode = parser.currentNode p = PlaceHolder(parser) parser.currentNode = p (methodName, names, types, brace, returnType, do) = FuncParser.funcHead(parser, decl, dontAdd=True, interfaceMethod=True) Scope.decrScope(parser) if methodName in meth: Error.parseError(parser, "Method " + methodName + ", already defined") meth[methodName] = brace.ftype parser.currentNode = currentNode parser.nextToken() else: Parser.declareOnly(parser, noVar=True) if len(parser.currentNode.nodes) > 0 and type( parser.currentNode.nodes[0]) is Tree.Create: Error.parseError( parser, "Interfaces are abstract interfaces which is why only methods are supported" ) names = {i.name: i.varType for i in parser.currentNode} #args = [i.varType for i in parser.currentNode] #fields = parser.currentNode.nodes if decl: i = interface.fromObj( Types.Interface(False, names, generic, parser.package + "." + name if parser.package != "_global" else name, methods=meth)) parser.interfaces[parser.package][name] = i Scope.decrScope(parser)
def f(parser): op = Tree.Operator(kind, parser) if kind == "|>": print(kind) if not kind in ["|>"] and len(parser.currentNode.nodes) != 0: if not unary and isUnary(parser, parser.lookBehind()): Error.parseError(parser, "unexpected " + kind) elif unary and not isUnary(parser, parser.lookBehind()): Error.parseError(parser, "unexpected " + kind) #parser.nodeBookmark.append(len(parser.currentNode.nodes)-1) Parser.Opcode(parser, kind, lambda: operatorPop(parser, op, takesIn, unary))
def hasMethod(self, parser, name): packages = [] b = None for i in parser.imports+[parser.package]+["_global"]: if not i in self.methods: continue if name in self.methods[i]: b = self.methods[i][name] b.package = i packages.append(i) if len(packages) > 1: Error.parseError(parser, "ambiguous, multiple definitions of the method "+self.name+"."+name+" in packages: "+", ".join(packages[:-1])+" and "+packages[-1]) return b
def externVar(parser): target = parser.nextToken() if target.type != "identifier": Error.parseError(parser, "expecting target") target = target.token if not target in ["client", "full", "node"]: Error.parseError(parser, target + " is not a valid compilation target") VarParser.createAndAssignParser(parser) parser.currentNode.nodes[-1].extern = True parser.currentNode.nodes[-1].global_target = target parser.currentNode.nodes[-1].nodes[1].extern = True
def importParser(parser, decl= False): import os name = parser.nextToken() if name.type != "str": Error.parseError(parser, "expecting string") oname = name.token[1:-1] if not oname in parser.filenames: Error.parseError(parser, "package "+oname+" not found") name = os.path.basename(oname) if not decl: parser.externFuncs[parser.package] = [] if not parser.hotswap: sp = shouldParse(decl, oname, parser) else: sp = shouldCompile(decl, oname, parser) if sp: p = Parser.Parser(parser.lexed[oname], parser.filenames[oname]) ResolveSymbols.insert(parser, p) sc = shouldCompile(decl, oname, parser) p.sc = sc parser.compiled[name] = None parser.externFuncs[name] = [] parsed = p.parse() declar = parser.externFuncs[name] parser.compiled[name] = (sc, (parsed, declar)) ResolveSymbols.insert(p, parser) parser.currentNode.addNode(Tree.InitPack(name, parser)) else: if not name in parser.compiled: parser.compiled[name] = (False,) parser.currentNode.addNode(Tree.InitPack(name, parser)) parser.imports.append(oname)
def newOperator(kind, precidence, takesIn, func=None, unary=False, token=True): def f(parser): op = Tree.Operator(kind, parser) if len(parser.currentNode.nodes) != 0: if not unary and isUnary(parser, parser.lookBehind()): Error.parseError(parser, "unexpected " + kind) elif unary and not isUnary(parser, parser.lookBehind()): Error.parseError(parser, "unexpected " + kind) #parser.nodeBookmark.append(len(parser.currentNode.nodes)-1) Parser.Opcode(parser, kind, lambda: operatorPop(parser, op, takesIn, unary)) if func == None: func = f Parser.precidences[kind] = precidence _f = lambda parser: Error.parseError( parser, "unexpected operator") if parser.lookBehind( ).type == "xoperator" else func(parser) if token: Parser.exprToken[kind] = _f else: operators[kind] = _f
def defer(parser): node = Tree.Defer(parser) previos = parser.currentNode previos.addNode(node) parser.currentNode = node while not Parser.isEnd(parser): parser.nextToken() Parser.callToken(parser) if len(node.nodes) != 1: Error.parseError(parser, "Expecting single expression, not "+str(len(node.nodes))) if not type(node.nodes[0]) is Tree.FuncCall: Error.parseError(parser, "Expecting function call") parser.currentNode = previos
def callFunc(parser, paren, onlyOneArg): if len(parser.currentNode.nodes) == 0: Error.parseError(parser, "Expecting identifier") tail = Tree.FuncCall(parser) tail.addNode(parser.currentNode.nodes[-1]) tail.owner = parser.currentNode parser.currentNode.nodes[-1] = tail parser.currentNode = tail if not paren: Parser.selectExpr(parser, parser.thisToken()) funcCallBody(parser, paren, onlyOneArg) parser.currentNode = tail.owner
def index(parser): if len(parser.currentNode.nodes) == 0: Error.parseError(parser, "unexpected .") field = parser.nextToken() if field.type != "identifier": Error.parseError(parser, "field name must be an identifer") field = field.token acess = Tree.Field(0, Types.Null(), parser) acess.addNode(parser.currentNode.nodes[-1]) acess.owner = parser.currentNode acess.field = field parser.currentNode.nodes[-1] = acess
def createAndAssignParser(parser, imutable= True): # let i assignment node = parser.currentNode parser.nextToken() #get current token to position of = checkIt = False attachTyp = False if parser.lookInfront().token == ".": attachTyp = Types.parseType(parser, attachTyp= True) parser.nextToken() if not imutable or not type(node) is Tree.Root: Error.parseError(parser, "expecting =, not .") parser.nextToken() name = parser.thisToken() typ = None if parser.nextToken().token == ":": checkIt = True parser.nextToken() typ = Types.parseType(parser) parser.nextToken() elif parser.thisToken().token != "=": Error.parseError(parser, "expecting =, not"+parser.thisToken().token) n = Tree.CreateAssign(parser) parser.currentNode.addNode(n) parser.currentNode = n createParser(parser, name= name, typ= typ, check= checkIt, imutable= imutable, attachTyp= attachTyp) if attachTyp: assignParser(parser, name=attachTyp.name+"_"+name.token, package= attachTyp.package, init=True) else: assignParser(parser, name= name.token, init= True) parser.currentNode = node
def checkIfOperator(parser, attachTyp, name, func): operators = { "add": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "sub": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "mul": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "div": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "eq": Types.FuncPointer([attachTyp, attachTyp], Types.Bool()), "ne": Types.FuncPointer([attachTyp, attachTyp], Types.Bool()), "mod": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "pow": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "gt": Types.FuncPointer([attachTyp, attachTyp], Types.Bool()), "lt": Types.FuncPointer([attachTyp, attachTyp], Types.Bool()), "set": Types.FuncPointer([attachTyp, Types.All], Types.Null(), do=True), } unary = { "add": Types.FuncPointer([attachTyp], attachTyp), "sub": Types.FuncPointer([attachTyp], attachTyp), "mul": Types.FuncPointer([attachTyp], attachTyp), "read": Types.FuncPointer([attachTyp], Types.All, do=True), } if name.startswith("operator_"): op = name[len("operator_"):] if not op in operators: Error.parseError(parser, "overload not found for operator_" + op) try: func.duckType(parser, operators[op], Tree.PlaceHolder(parser), Tree.PlaceHolder(parser), 0) except EOFError as e: Error.beforeError(e, "Operator overload: ") elif name.startswith("unary_"): op = name[len("unary_"):] if not op in unary: Error.parseError(parser, "overload not found for unary_" + op) try: unary[op].duckType(parser, func, Tree.PlaceHolder(parser), Tree.PlaceHolder(parser), 0) except EOFError as e: Error.beforeError(e, "Unary overload: ")
def importParser(parser, decl= False): import os name = parser.nextToken() if name.type != "str": Error.parseError(parser, "expecting string") oname = name.token[1:-1] if not oname in parser.filenames: Error.parseError(parser, "package "+oname+" not found") name = os.path.basename(oname) if not decl: parser.externFuncs[parser.package] = [] if shouldParse(decl, oname, parser): p = Parser.Parser(parser.lexed[oname], parser.filenames[oname]) ResolveSymbols.insert(parser, p) sc = shouldCompile(decl, oname, parser) parser.compiled[name] = None parser.externFuncs[name] = [] if sc: parsed = p.parse() else: parsed = None declar = parser.externFuncs[name] parser.compiled[name] = (sc, (parsed, declar)) ResolveSymbols.insert(p, parser) parser.currentNode.addNode(Tree.InitPack(name, parser)) else: if not name in parser.compiled: parser.compiled[name] = None parser.imports.append(oname)
def pushContext(parser): parser.nextToken() node = Tree.PushContext(parser) previous = parser.currentNode previous.addNode(node) parser.currentNode = node Parser.callToken(parser) if len(node.nodes) == 0 or not type(node.nodes[0]) is Tree.ReadVar: Error.parseError(parser, "Expecting identifier") if parser.nextToken().token != "do": Error.parseError(parser, "Expecting do") while not Parser.isEnd(parser) or parser.thisToken().token == "do": parser.nextToken() Parser.callToken(parser) parser.currentNode = previous
def parserMethodGen(parser, gen, struct): sgen = struct.generic if len(gen) > len(sgen): Error.parseError( parser, str(len(gen) - len(sgen)) + " generic arguments too many") elif len(gen) < len(sgen): Error.parseError( parser, str(len(gen) - len(sgen)) + " generic arguments too few") newGen = coll.OrderedDict() for a, b in zip(gen, sgen): typ = sgen[b] aStripped = a[a.rfind(".") + 1:] if not a in sgen: Error.parseError( parser, "Unknown type parameter " + aStripped + " in " + str(struct)) if gen[a].type != Types.All: typ = gen[ b] #@cleanup check if interface is compatible with structs regular generics Error.parseError(parser, "unexpected :") newGen[a] = typ Scope.changeType(parser, aStripped, typ) return newGen
def addToContext(parser): previous = parser.currentNode node = Tree.AddToContext(parser) parser.currentNode = node if not type(previous) is Tree.Root: Error.parseError(parser, "Can only add field to context from global scope") if parser.nextToken().type != "identifier": Error.parseError(parser, "Expecting identifier") Parser.callToken(parser) parser.nextToken() iter = parser.iter+1 line = parser.lineNumber Parser.callToken(parser) if not type(node.nodes[0]) is Tree.CreateAssign: parser.iter = iter parser.lineNumber = line Error.parseError(parser, "Expecting :=") createAssign = node.nodes[0] node.name = createAssign.nodes[0].name parser.currentNode = previous previous.addNode(node)
def getName(token, nameOfVar=""): if nameOfVar == "": nameOfVar = token.token package = parser.package if nameOfVar in parser.structs[name]: if decl: if stage and nameOfVar in parser.structs[package]: Error.parseError(parser, nameOfVar + " is already a struct") parser.structs[package][nameOfVar] = parser.structs[name][ nameOfVar] else: pass #Scope.addVar(place, parser, nameOfVar, parser.scope[name][0][nameOfVar]) names.append((nameOfVar, "full")) elif nameOfVar in parser.interfaces[name]: if not decl: return if stage and nameOfVar in parser.interfaces[package]: Error.parseError(parser, nameOfVar + " is already an interface") parser.interfaces[package][nameOfVar] = parser.interfaces[name][ nameOfVar] elif not decl and nameOfVar in parser.scope[name][0]: #can't set lambda Scope.addVar(place, parser, nameOfVar, parser.scope[name][0][nameOfVar]) names.append((nameOfVar, parser.scope[name][0][nameOfVar].target)) elif not decl: Error.parseError( parser, "Package " + name + " does not have a variable, or type called " + nameOfVar)
def operatorPop(parser, op, takesIn, unary= False): kind = op.kind op.unary = unary parser.currentNode.addNode(op) count = 0 min = -1 - takesIn #print(parser.currentNode.nodes[parser.nodeBookmark[-1]:]) #print("=====") use = parser.nodeBookmark[-1] #if len(parser.bookmark) > 1 and len(parser.stack) > parser.bookmark[-2]+1: # last = parser.stack[-2].pos #else: # last = 0 #use = last if nb < last else nb for i in parser.currentNode.nodes[use:][min:-1]: parser.currentNode.nodes[-1].addNode(i) count += 1 if count < takesIn: print(count) print(unary) print(parser.currentNode.nodes) print(takesIn) print(min) print(use) Error.parseError(parser, "Too few values to operate on for operator " + op.kind) op.curry = True del parser.currentNode.nodes[-1 -len(op.nodes):-1] #parser.currentNode.nodes[:-1 - len(op.nodes)] + [op] #parser.nodeBookmark.pop() pass
def aliasParser(parser, name, decl, generic): parser.nextToken() typ = False while not Parser.isEnd(parser): if parser.thisToken().token != "\n" and parser.thisToken( ).type != "indent": if typ: Error.parseError( parser, "Unexpected token " + parser.thisToken().token) typ = Types.parseType(parser) parser.nextToken() alias = Types.Alias(parser.package, name, typ, generic) if decl: del parser.structs[parser.package][ name] # = Struct.Struct(name, args, fields, coll.OrderedDict()) parser.interfaces[parser.package][name] = alias Scope.decrScope(parser)
def returnF(parser): previous = parser.currentNode parser.nodeBookmark.append(0) if type(previous) is Tree.Root: Error.parseError(parser, "Can only return from function") returnAST = Tree.Return(parser) previous.addNode(returnAST) parser.currentNode = returnAST while not Parser.isEnd(parser): parser.nextToken() Parser.callToken(parser) if len(returnAST.nodes) > 1: Error.parseError( parser, "Expecting single expression not " + str(len(returnAST.nodes))) parser.currentNode = previous parser.nodeBookmark.pop()
def typeParser(parser, decl= False): name = parser.nextToken() Scope.incrScope(parser) if name.type != "identifier": Error.parseError(parser, "type name must be an identifier") name = name.token if name[0].lower() == name[0]: Error.parseError(parser, "struct name must be upper case") import collections as coll gen = coll.OrderedDict() if parser.nextToken().token == "[": gen = FuncParser.generics(parser, name) if parser.thisToken().token != "=": if parser.thisToken().token == "with": tmp = parser.currentNode parser.currentNode = Tree.PlaceHolder(parser) Interface.traitParser(parser, name, decl, gen) parser.currentNode = tmp return Error.parseError(parser, "expecting =") tmp = parser.currentNode typ = Tree.Type(parser.package, name, parser) typ.package = parser.package typ.normalName = name tmp.addNode(typ) parser.currentNode = typ while not Parser.isEnd(parser): parser.nextToken() Parser.declareOnly(parser, noVar=True) args = [i.varType for i in parser.currentNode] fields = parser.currentNode.nodes typ.fields = [i.name for i in typ] typ.nodes = [] parser.currentNode = tmp if decl: meth = parser.structs[parser.package][name].methods parser.structs[parser.package][name] = Struct(name, args, fields, gen) parser.structs[parser.package][name].methods = meth parser.structs[parser.package][name].package = parser.package Scope.decrScope(parser)
def initStruct(parser, package= ""): if ExprParser.isUnary(parser, parser.lookBehind()): Error.parseError(parser, "unexpected {") if package == "": package = parser.package if len(parser.currentNode.nodes) == 0: Error.parseError(parser, "unexpected {") if not type(parser.currentNode.nodes[-1]) in [Tree.ReadVar, Tree.Field]: Error.parseError(parser, "unexpected {") readVar = type(parser.currentNode.nodes[-1]) is Tree.ReadVar name = parser.currentNode.nodes[-1].name if readVar else parser.currentNode.nodes[-1].field init = Tree.InitStruct(parser) if not readVar: package = parser.currentNode.nodes[-1].nodes[0].name t = (parser.currentNode.nodes[-1].nodes[0]) if not package in parser.imports: t.error("no package called " + package) elif not type(t) is Tree.ReadVar: init.error("unexpected {") init.package = package del parser.currentNode.nodes[-1] s = parser.structs[package][name] init.paramNames = offsetsToList(parser.structs[package][name].offsets) init.s = s init.mutable = False parser.currentNode.addNode(init) parser.currentNode = init parser.nextToken() while parser.thisToken().token != "}": if parser.thisToken().token == ",": ExprParser.endExpr(parser) else: Parser.callToken(parser) parser.nextToken() t = parser.thisToken().token continue ExprParser.endExpr(parser) parser.currentNode = init.owner
def parserMethodGen(parser, gen, struct): sgen = struct.generic if len(gen) > len(sgen): Error.parseError(parser, str(len(gen)-len(sgen))+" generic arguments too many") elif len(gen) < len(sgen): Error.parseError(parser, str(len(gen) - len(sgen)) + " generic arguments too few") newGen = coll.OrderedDict() for a, b in zip(gen, sgen): if gen[a].type != Types.All: Error.parseError(parser, "unexpected :") newGen[a] = sgen[b] Scope.changeType(parser, a, sgen[b]) return newGen
def checkIfOperator(parser, attachTyp, name, func): operators = { "add": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "sub": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "mul": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "div": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "eq": Types.FuncPointer([attachTyp, attachTyp], Types.Bool()), "ne": Types.FuncPointer([attachTyp, attachTyp], Types.Bool()), "mod": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "pow": Types.FuncPointer([attachTyp, attachTyp], attachTyp), "gt": Types.FuncPointer([attachTyp, attachTyp], Types.Bool()), "lt": Types.FuncPointer([attachTyp, attachTyp], Types.Bool()), } unary = { "add": Types.FuncPointer([attachTyp], attachTyp), "sub": Types.FuncPointer([attachTyp], attachTyp), "mul": Types.FuncPointer([attachTyp], attachTyp) } if name.startswith("operator_"): op = name[len("operator_"):] if not op in operators: Error.parseError(parser, "overload not found for operator_"+op) f = Types.FuncPointer(func.args, func.returnType) if f != operators[op]: Error.parseError(parser, "expecting function declaration "+str(operators[op])+", not "+str(f)) elif name.startswith("unary_"): op = name[len("unary_"):] if not op in unary: Error.parseError(parser, "overload not found for unary_"+op) f = Types.FuncPointer(func.args, func.returnType) if f != unary[op]: Error.parseError(parser, "expecting function declaration "+str(unary[op])+", not "+str(f))
parser.currentNode.addNode(n) parser.currentNode.addNode(cond) parser.currentNode = cond while not Parser.isEnd(parser): token = parser.nextToken() iter = parser.iter if token.token == "do" : ExprParser.endExpr(parser) block = Tree.WhileBlock(parser) cond.owner.addNode(block) parser.currentNode = block continue Parser.callToken(parser) ExprParser.endExpr(parser) parser.currentNode = n.owner.owner Parser.exprToken["while"] = whileExpr Parser.exprToken["break"] = lambda parser: parser.currentNode.addNode(Tree.Break(parser)) Parser.exprToken["continue"] = lambda parser: parser.currentNode.addNode(Tree.Continue(parser)) Parser.exprToken["then"] = lambda parser: Error.parseError(parser, "unexpected then keyword") Parser.exprToken["do"] = lambda parser: Error.parseError(parser, "unexpected do keyword")
def funcHead(parser, decl= False, dontAdd= False, method= False, attachTyp = False): Scope.incrScope(parser) if parser.tokens[parser.iter+2].token == ".": if attachTyp: Error.parseError(parser, "unexpected .") parser.nextToken() name = parser.thisToken().token parser.nextToken() try: attachTyp = Types.Struct(False, name, parser.structs[parser.package][name].types, parser.package, {}) except KeyError: Error.parseError(parser, "no attachable data structure found, called "+name) return funcHead(parser, decl, dontAdd, True, attachTyp) name = parser.nextToken() if name.type != "identifier": Error.parseError(parser, "function name must be of type identifier, not "+name.type) parser.nextToken() name = name.token g = {} if parser.thisToken().token != "(": if parser.thisToken().token == "[": g = generics(parser, (str(attachTyp)+"." if method else "")+name) if parser.thisToken().token == ".": if attachTyp: Error.parseError(parser, "unexpected .") if not Scope.varExists(parser, parser.package, name): Error.parseError(parser, "cannot attach method to unknown type main."+name) try: attachTyp = Types.Struct(False, name, parser.structs[parser.package][name].types, parser.package, parserMethodGen(parser, g, parser.structs[parser.package][name])) except KeyError: Error.parseError(parser, "no attachable data structure found, called " + name) return funcHead(parser, decl, dontAdd, True, attachTyp) if parser.thisToken().token != "(": Error.parseError(parser, "expecting (") header = Tree.FuncStart(name, Types.Null(), parser) header.package = parser.package parser.currentNode.addNode(header) brace = Tree.FuncBraceOpen(parser) brace.name = name brace.package = parser.package parser.currentNode.addNode(brace) parser.currentNode = brace if method: if not type(parser.currentNode.owner) is Tree.Root and not decl: Error.parseError(parser, "method extension must be in out-most scope") typ = attachTyp self = parser.nextToken() if self.type != "identifier": Error.parseError(parser, "binding name must be identifier not "+self.type) self = self.token selfNode = Tree.Create(self, typ, parser) selfNode.package = parser.package selfNode.imutable = True parser.currentNode.addNode(selfNode) if not parser.lookInfront().token in [")", ","]: Error.parseError(parser, "expecting comma not "+parser.thisToken().token) if name[0].lower() != name[0]: Error.parseError(parser, "function name must be lower case") returnType = Types.Null() parser.paren += 1 parser.nextToken() while parser.paren != parser.parenBookmark[-1] : b = parser.thisToken().token if b == ",": parser.nextToken() continue elif b == ")": parser.paren -= 1 parser.nextToken() continue elif b == "(": Error.parseError(parser, "unexpected (") Parser.declareOnly(parser) parser.nextToken() t = parser.thisToken() do = False if t.token != "=" and t.token != "do": returnType = Types.parseType(parser) t = parser.nextToken() if t.token != "=" and t.token != "do": Error.parseError(parser, "expecting = or do") if t.token == "do": do = True parser.currentNode = brace.owner names = [i.name for i in brace.nodes] types = [i.varType for i in brace.nodes] func = Types.FuncPointer( types, returnType, g, do ) if method: Scope.decrScope(parser) header.method = True header.types = types[1:] header.attachTyp = attachTyp header.normalName = name header.name = attachTyp.normalName+"_"+header.normalName MethodParser.checkIfOperator(parser, attachTyp, name, func) if decl: MethodParser.addMethod(brace, parser, attachTyp, name, func) return attachTyp.normalName+"_"+name, names, types, header, returnType, do parser.func[parser.package][name] = func header.ftype = Types.FuncPointer(types, returnType, g) if decl: if not dontAdd: Scope.addFunc(header, parser, name, Types.FuncPointer(types, returnType, g, do)) return name, names, types, header, returnType, do
generic = Tree.Generic(parser) parser.currentNode.addNode(generic) generic.addNode(func) generic.generic = [] if parser.thisToken().token != "[": Error.parseError(parser, "expecting [") parser.nextToken() while parser.thisToken().token != "]": if parser.thisToken().token == ",": parser.nextToken() parser.nodeBookmark[-1] = len(parser.currentNode.nodes) continue generic.generic.append(Types.parseType(parser)) t = parser.thisToken().token parser.nextToken() def under(parser): parser.currentNode.addNode(Tree.Under(parser)) Parser.stmts["def"] = func Parser.exprToken["none"] = lambda parser: Error.parseError(parser, "unexpected type none") Parser.exprToken[","] = lambda parser: Error.parseError(parser, "unexpected ,") Parser.exprToken["_"] = under Parser.exprToken["::"] = genericT Parser.exprToken["!"] = lambda parser: 0
createParser(parser, name= name, typ= typ, check= checkIt, imutable= imutable, attachTyp= attachTyp) if attachTyp: assignParser(parser, name=attachTyp.name+"_"+name.token, package= attachTyp.package, init=True) else: assignParser(parser, name= name.token, init= True) parser.currentNode = node Parser.stmts["let"] = createAndAssignParser Parser.stmts["var"] = lambda parser: createAndAssignParser(parser, imutable= False) Parser.stmts["="] = assignParser Parser.stmts[":"] = createParser Parser.exprToken["i32"] = lambda parser: Error.parseError(parser, "unexpected type int") Parser.exprToken["|"] = lambda parser: Error.parseError(parser, "unexpected function declaration") Parser.exprToken["int"] = lambda parser: Error.parseError(parser, "unexpected type int") Parser.exprToken["float"] = lambda parser: Error.parseError(parser, "unexpected type float") Parser.exprToken["bool"] = lambda parser: Error.parseError(parser, "unexpected type bool") def read(parser, name, package= ""): if package == "": package = parser.package node = Tree.ReadVar(name, False, parser) node.package = package parser.currentNode.addNode(node) def equalAnd(parser, operator, package= ""): if package == "": package = parser.package