ParseResult monomod() { ParseResult res = new ParseResult(); PNode node; if (current.type == TokenType.INC || current.type == TokenType.DEC) { LToken op = current; res.Register(Next()); node = res.Register(call(newer())); if (res.error != null) { return(res); } if (op.type == TokenType.INC) { op.type = TokenType.ADD; } else { op.type = TokenType.SUB; } PNode exp = PNode.GetBinOP(node, op, new PNode(new LToken(TokenType.VALUE, new Value(1), op.position))); if (node.TYPE == "VarGet") { return(res.Succes(new PNode("VarAsign", node.val, exp))); } if (!res.isInnnerCall) { return(res.Failure(new InvalidSyntaxError(op.position, "Increment and decrement operators can only edit immediate variables"))); } List <PNode> pns = new List <PNode>(node.PNodes); pns.RemoveAt(0); pns.Add(exp); return(res.Succes(PNode.GetCall("InnerAsign", node.PNodes[0], pns))); } node = res.Register(call(newer())); if (current.type == TokenType.INC || current.type == TokenType.DEC) { LToken op = current; LToken ed = current.Copy(false); if (!res.isInnnerCall && node.TYPE != "VarGet") { return(res.Failure(new InvalidSyntaxError(op.position, "Increment and decrement operators can only edit immediate variables"))); } res.Register(Next()); if (op.type == TokenType.INC) { ed.type = TokenType.ADD; } else { ed.type = TokenType.SUB; } PNode exp = PNode.GetBinOP(node, ed, new PNode(new LToken(TokenType.VALUE, new Value(1), op.position))); if (node.TYPE == "VarGet") { exp = new PNode("VarAsign", node.val, exp); } else { List <PNode> pns = new List <PNode>(node.PNodes); pns.RemoveAt(0); pns.Add(exp); exp = PNode.GetCall("InnerAsign", node.PNodes[0], pns); } return(res.Succes(new PNode("UnarOp", new List <PNode>() { node, exp }, op))); } return(res.Succes(node, true)); }
ParseResult expr() { ParseResult res = new ParseResult(); bool publish = false; if (current.type == TokenType.KEYWORD && current.value.text == "public") { res.Register(Next()); if (current.type == TokenType.KEYWORD && current.value.text == "function") { PNode fd = res.Register(Func_Def()); if (res.error != null) { return(res); } if (fd.val.value == null) { return(res.Failure(new InvalidSyntaxError(fd.val.position, "Public function can not be anonymous."))); } fd.TYPE = "PublicFuncDeff"; return(res.Succes(fd)); } if (current.type == TokenType.KEYWORD && current.value.text == "let") { publish = true; } else { return(res.Failure(new InvalidSyntaxError(current.position, "Expected let or function"))); } } if (current.type == TokenType.KEYWORD && current.value.text == "let") { res.Register(Next()); if (current.type != TokenType.IDENTIFIER) { return(res.Failure(new InvalidSyntaxError(current.position, "Expected an identifier"))); } LToken Vname = current; PNode exp = new PNode(new LToken(TokenType.VALUE, Value.NULL, current.position));; res.Register(Next()); if (current.type == TokenType.EQUAL) { res.Register(Next()); exp = res.Register(expr()); if (res.error != null) { return(res); } } if (publish) { return(res.Succes(new PNode("PublicVarMake", Vname, exp))); } return(res.Succes(new PNode("VarMake", Vname, exp))); } if (publish) { return(res.Failure(new InvalidSyntaxError(current.position, "Expected let or function."))); } if (current.type == TokenType.IDENTIFIER) { LToken Vname = current; res.Register(Next()); if ((current.type & TokenType.EQUAL) != 0) { TokenType t = current.type; res.Register(Next()); PNode exp = res.Register(expr()); if (res.error != null) { return(res); } if ((t & (TokenType.ADD | TokenType.SUB | TokenType.MULT | TokenType.DIV | TokenType.POW)) != 0) { exp = PNode.GetBinOP(new PNode("VarGet", Vname), new LToken(t ^ TokenType.EQUAL), exp); } return(res.Succes(new PNode("VarAsign", Vname, exp))); } res.Register(Back()); } PNode node = res.Register(BinOP(comp_expr, TokenType.AND | TokenType.OR)); if (res.error != null) { return(res.Failure(new InvalidSyntaxError(current.position, "Expected, let, number, identifier, plus, minus or parenthesis"))); } if (current.type == TokenType.MOVL) { res.Register(Next()); if (current.type != TokenType.IDENTIFIER) { return(res.Failure(new InvalidSyntaxError(current.position, "Expected an identifier"))); } LToken Pname = current; PNode exp = new PNode(new LToken(TokenType.VALUE, Value.NULL, current.position)); res.Register(Next()); if (current.type == TokenType.EQUAL) { res.Register(Next()); exp = res.Register(expr()); if (res.error != null) { return(res); } } return(res.Succes(new PNode("Prototype", new List <PNode>() { node, exp }, Pname))); } if (res.isInnnerCall) { if ((current.type & TokenType.EQUAL) != 0) { TokenType t = current.type; res.Register(Next()); PNode exp = res.Register(expr()); if (res.error != null) { return(res); } if ((t & (TokenType.ADD | TokenType.SUB | TokenType.MULT | TokenType.DIV | TokenType.POW)) != 0) { exp = PNode.GetBinOP(node, new LToken(t ^ TokenType.EQUAL), exp); } if (node.TYPE == "GetInner") { List <PNode> pns = new List <PNode>(node.PNodes); pns.RemoveAt(0); pns.Add(exp); return(res.Succes(PNode.GetCall("InnerAsign", node.PNodes[0], pns))); } return(res.Succes(PNode.GetCall("PropertyAsign", node, new List <PNode>() { exp }))); } } return(res.Succes(node)); }
ParseResult call(ParseResult toCall) { ParseResult res = new ParseResult(); PNode at = res.Register(toCall); if (res.error != null) { return(res); } if (current.type == TokenType.LPAR) { res.Register(Next()); List <PNode> args = new List <PNode>(); if (current.type == TokenType.RPAR) { res.Register(Next()); } else { args.Add(res.Register(expr())); if (res.error != null) { return(res.Failure(new InvalidSyntaxError(res.error.position, res.error.message + " or expected ')'"))); } while (current.type == TokenType.COMMA) { res.Register(Next()); args.Add(res.Register(expr())); if (res.error != null) { return(res); } } if (current.type != TokenType.RPAR) { return(res.Failure(new InvalidSyntaxError(current.position, "Expected ',' or ')'"))); } res.Register(Next()); } return(call(res.Succes(PNode.GetCall("CallFunc", at, args)))); } else if (current.type == TokenType.LSQBR) { res.Register(Next()); if (current.type == TokenType.RSQBR) { return(res.Failure(new InvalidSyntaxError(current.position, "Expected int"))); } PNode n = res.Register(expr()); if (current.type != TokenType.RSQBR) { return(res.Failure(new InvalidSyntaxError(current.position, "Expected ']'"))); } res.Register(Next()); res.isInnnerCall = true; return(call(res.Succes(PNode.GetCall("GetInner", at, new List <PNode>() { n }), true))); } else if (current.type == TokenType.DOT) { res.Register(Next()); if (current.type != TokenType.IDENTIFIER) { return(res.Failure(new InvalidSyntaxError(current.position, "Expected identifier"))); } LToken id = current; res.Register(Next()); if (current.type == TokenType.LPAR) { res.Register(Next()); List <PNode> args = new List <PNode>(); if (current.type == TokenType.RPAR) { res.Register(Next()); } else { args.Add(res.Register(expr())); if (res.error != null) { return(res.Failure(new InvalidSyntaxError(res.error.position, res.error.message + " or expected ')'"))); } while (current.type == TokenType.COMMA) { res.Register(Next()); args.Add(res.Register(expr())); if (res.error != null) { return(res); } } if (current.type != TokenType.RPAR) { return(res.Failure(new InvalidSyntaxError(current.position, "Expected ',' or ')'"))); } res.Register(Next()); } PNode RET = PNode.GetCall("CallProperty", at, args); RET.val = id; return(call(res.Succes(RET))); } res.isInnnerCall = true; return(call(res.Succes(new PNode("GetProperty", id, at), true))); } return(res.Succes(at, true)); }