private RuntimeResult VisitLoadNode(LoadNode node, Context context) { string fname = node.Token.Value.ToString(); string fileName = ""; if (File.Exists(Program.FileDirectory + fname + Program.LibraryExt)) { fileName = Program.FileDirectory + fname + Program.LibraryExt; } else if (File.Exists(Program.FileDirectory + "libs\\" + fname + Program.LibraryExt)) { fileName = Program.FileDirectory + "libs\\" + fname + Program.LibraryExt; } else if (File.Exists(Program.FileDirectory + fname + ".si")) { fileName = Program.FileDirectory + fname + ".si"; } else if (File.Exists(Program.FileDirectory + "libs\\" + fname + ".si")) { fileName = Program.FileDirectory + "libs\\" + fname + ".si"; } else if (File.Exists(Program.BaseDirectory + fname + Program.LibraryExt)) { fileName = Program.BaseDirectory + fname + Program.LibraryExt; } else if (File.Exists(Program.BaseDirectory + "libs\\" + fname + Program.LibraryExt)) { fileName = Program.BaseDirectory + fname + "libs\\" + Program.LibraryExt; } else if (File.Exists(Program.BaseDirectory + fname + ".si")) { fileName = Program.BaseDirectory + fname + ".si"; } else if (File.Exists(Program.BaseDirectory + "libs\\" + fname + ".si")) { fileName = Program.BaseDirectory + "libs\\" + fname + ".si"; } if (fileName.Equals("")) { return(new RuntimeResult(new RuntimeError(node.Token.Position, "Assembly '" + fname + "' not found!", context))); } if (fileName.EndsWith(Program.LibraryExt)) { if (node.ClassToken != null) { Values.AssemblyValue value = new Values.AssemblyValue(); value.SetPositionAndContext(node.Token.Position, context); value.LoadAsm("libs\\" + fname + Program.LibraryExt, fname, node.ClassToken.Value.ToString()); context.AddSymbol(node.ClassToken.Value.ToString(), value); return(new RuntimeResult(value)); } else { //todo fix this system Assembly asm = Assembly.LoadFile(fileName); Type[] types = asm.GetTypes(); for (int i = 0; i < types.Length; i++) { Console.WriteLine(types[i].Name); } for (int i = 0; i < types.Length; i++) { Values.AssemblyValue value = new Values.AssemblyValue(); value.Assembly = asm; value.AsmType = types[i]; FieldInfo[] fields = types[i].GetFields(); for (int j = 0; j < fields.Length; j++) { context.AddSymbol(fields[j].Name, Values.AssemblyValue.ParseValue(fields[j].GetValue(null), node.Token.Position, context)); } value.SetPositionAndContext(node.Token.Position, context); context.AddSymbol(types[i].Name, value); if (i == types.Length - 1) { return(new RuntimeResult(value)); } } } } else { string code = File.ReadAllText(fileName).Replace("\r\n", "\n"); Tokenizer tokenizer = new Tokenizer(fname, code); TokenizerResult tokenizerResult = tokenizer.GenerateTokens(); if (!tokenizerResult.HasError) { Parser parser = new Parser(tokenizerResult.Tokens); ParserResult parserResult = parser.Parse(); if (!parserResult.HasError) { Interpreter interpreter = new Interpreter(); return(interpreter.Visit(parserResult.Node, context)); } else { return(new RuntimeResult(parserResult.Error)); } } else { return(new RuntimeResult(tokenizerResult.Error)); } } return(new RuntimeResult(new RuntimeError(node.Token.Position, "Library " + fname + " not found!", context))); }
private ParserResult Atom(bool byPassDot = false) { Token token = currentToken; if (token.Type == TokenType.INTEGER || token.Type == TokenType.LONG || token.Type == TokenType.FLOAT || token.Type == TokenType.BIGINTEGER || token.Type == TokenType.COMPLEX || token.Type == TokenType.BYTE_ARRAY) { Advance(); return(new ParserResult(new NumberNode(token))); } else if (token.Type == TokenType.STRING) { Advance(); if (currentToken.Type == TokenType.LEFT_SQB) { return(Subscript(new StringNode(token))); } return(new ParserResult(new StringNode(token))); } else if (token.Type == TokenType.IDENTIFIER) { Advance(); if (currentToken.Type == TokenType.LEFT_SQB) { return(Subscript(new VarAccessNode(token))); } if (!byPassDot && currentToken.Type == TokenType.DOT) { return(Attribute(new VarAccessNode(token))); } if (currentToken.Type == TokenType.EQUALS) { Advance(); ParserResult exprResult = Expr(); if (exprResult.HasError) { return(exprResult); } return(new ParserResult(new VarAssignNode(token, exprResult.Node))); } if (currentToken.Type == TokenType.COLON && Peek(2).Type == TokenType.EQUALS) { Advance(); Token typeToken = currentToken; //todo check is it a valid keyword Advance(2); ParserResult exprResult = Expr(); if (exprResult.HasError) { return(exprResult); } return(new ParserResult(new VarAssignNode(token, exprResult.Node, typeToken))); } return(new ParserResult(new VarAccessNode(token))); } else if (token.Type == TokenType.LEFT_PAREN) { Advance(); ParserResult exprResult = Expr(); if (exprResult.HasError) { return(exprResult); } if (currentToken.Type != TokenType.RIGHT_PAREN) { return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected ')'"))); } Advance(); return(exprResult); } else if (token.Type == TokenType.LEFT_SQB) { return(ListExpr()); } else if (token.Type == TokenType.LEFT_BRA) { return(DictionaryExpr()); } else if (token.CheckKeyword("if")) { return(IfStmt()); } else if (token.CheckKeyword("for")) { if (Peek().CheckKeyword("each")) { return(ForEachStmt()); } return(ForStmt()); } else if (token.CheckKeyword("while")) { return(WhileStmt()); } else if (token.CheckKeyword("do")) { return(DoStmt()); } else if (token.CheckKeyword("when")) { return(WhenStmt()); } else if (token.CheckKeyword("method")) { return(Method()); } else if (token.CheckKeyword("class")) { return(Class()); } else if (token.CheckKeyword("load")) { return(LoadStmt()); } else if (token.CheckKeyword("return")) { return(ReturnStmt()); } else if (token.CheckKeyword("break")) { Advance(); return(new ParserResult(new BreakNode().SetPosition(currentToken.Position))); } else if (token.CheckKeyword("continue")) { Advance(); return(new ParserResult(new ContinueNode().SetPosition(currentToken.Position))); } return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected int or float"))); }
private ParserResult Method() { //todo avoid use true,false,null as param names Advance(); Token token = null; List <string> parameters = new List <string>(); Dictionary <string, Node> defaUltValues = new Dictionary <string, Node>(); if (currentToken.Type == TokenType.IDENTIFIER || currentToken.Type == TokenType.PLUS || currentToken.Type == TokenType.MINUS || currentToken.Type == TokenType.MULTIPLY || currentToken.Type == TokenType.DIVIDE || currentToken.Type == TokenType.MODULUS || currentToken.Type == TokenType.EXPONENT || currentToken.Type == TokenType.STRING || currentToken.Type == TokenType.IN || currentToken.Type == TokenType.LESS_THAN || currentToken.Type == TokenType.LESS_TOE || currentToken.Type == TokenType.GREATER_THAN || currentToken.Type == TokenType.GREATER_TOE || currentToken.Type == TokenType.EQUALS_EQUALS || currentToken.Type == TokenType.NOT_EQUALS || currentToken.Type == TokenType.BITWISE_AND || currentToken.Type == TokenType.BITWISE_OR || currentToken.Type == TokenType.BITWISE_XOR || currentToken.Type == TokenType.COMPLEMENT || currentToken.Type == TokenType.LEFT_SHIFT || currentToken.Type == TokenType.RIGHT_SHIFT || currentToken.Type == TokenType.BOOLEAN_AND || currentToken.Type == TokenType.BOOLEAN_OR || currentToken.Type == TokenType.BOOLEAN_NOT) { token = currentToken; Advance(); } else if (currentToken.Type == TokenType.LEFT_SQB && Peek().Type == TokenType.RIGHT_SQB) { token = currentToken; Advance(2); } else if (currentToken.Type == TokenType.LEFT_SQB && Peek().Type == TokenType.EQUALS && Peek(2).Type == TokenType.RIGHT_SQB) { Advance(); token = currentToken; Advance(2); } if (currentToken.Type != TokenType.LEFT_PAREN) { return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected '('"))); } Advance(); if (currentToken.Type == TokenType.RIGHT_PAREN) { Advance(); } else { if (currentToken.Type != TokenType.IDENTIFIER) { return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected an identifer"))); } string paramName = currentToken.Value.ToString(); parameters.Add(paramName); Advance(); if (currentToken.Type == TokenType.EQUALS) { Advance(); ParserResult result = BitwiseOr(); if (result.HasError) { return(result); } defaUltValues.Add(paramName, result.Node); } while (currentToken.Type == TokenType.COMMA) { Advance(); if (currentToken.Type != TokenType.IDENTIFIER) { return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected an identifer or ')'"))); } paramName = currentToken.Value.ToString(); parameters.Add(paramName); Advance(); if (currentToken.Type == TokenType.EQUALS) { Advance(); ParserResult result = BitwiseOr(); if (result.HasError) { return(result); } defaUltValues.Add(paramName, result.Node); } } if (currentToken.Type != TokenType.RIGHT_PAREN) { return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ')'"))); } Advance(); } if (currentToken.Type == TokenType.COLON) { Advance(); SkipNewLines(); ParserResult parserResult = Expr(); if (parserResult.HasError) { return(parserResult); } return(new ParserResult(new MethodNode(token, parameters, parserResult.Node, defaUltValues).SetPosition(currentToken.Position))); } else { SkipNewLines(); if (currentToken.Type == TokenType.LEFT_BRA) { Advance(); SkipNewLines(); ParserResult parserResult = Block(); if (parserResult.HasError) { return(parserResult); } Advance(); return(new ParserResult(new MethodNode(token, parameters, parserResult.Node, defaUltValues).SetPosition(currentToken.Position))); } else { return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected '{' or ':'"))); } } }
private ParserResult ForStmt() { Node start, end; Node step = null; Advance(); Token token = currentToken; if (token.Type != TokenType.IDENTIFIER) { return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected an identifier"))); } Advance(); if (currentToken.Type != TokenType.EQUALS) { return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected '='"))); } Advance(); ParserResult startResult = BitwiseOr(); if (startResult.HasError) { return(startResult); } start = startResult.Node; if (!currentToken.CheckKeyword("to")) { return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected keyword 'to'"))); } Advance(); ParserResult endResult = BitwiseOr(); if (endResult.HasError) { return(endResult); } end = endResult.Node; if (currentToken.CheckKeyword("step")) { Advance(); ParserResult stepResult = BitwiseOr(); if (stepResult.HasError) { return(stepResult); } step = stepResult.Node; } if (currentToken.Type == TokenType.COLON) { Advance(); SkipNewLines(); ParserResult parserResult = Expr(); if (parserResult.HasError) { return(parserResult); } return(new ParserResult(new ForNode(token, start, end, step, parserResult.Node))); } else { SkipNewLines(); if (currentToken.Type == TokenType.LEFT_BRA) { Advance(); SkipNewLines(); ParserResult parserResult = Block(); if (parserResult.HasError) { return(parserResult); } Advance(); return(new ParserResult(new ForNode(token, start, end, step, parserResult.Node))); } else { return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected ':' or '{'"))); } } }
private ParserResult IfStmt() { Advance(); List <(Node, Node)> cases = new List <(Node, Node)>(); Node elseCase = null; ParserResult condResult = Expr(); if (condResult.HasError) { return(condResult); } if (currentToken.Type == TokenType.COLON) { Advance(); SkipNewLines(); ParserResult caseResult = Expr(); if (caseResult.HasError) { return(caseResult); } cases.Add((condResult.Node, caseResult.Node)); SkipNewLines(); while (currentToken.CheckKeyword("elif")) { Advance(); condResult = Expr(); if (condResult.HasError) { return(condResult); } if (currentToken.Type == TokenType.COLON) { Advance(); SkipNewLines(); caseResult = Expr(); if (caseResult.HasError) { return(caseResult); } cases.Add((condResult.Node, caseResult.Node)); SkipNewLines(); } else { SkipNewLines(); if (currentToken.Type == TokenType.LEFT_BRA) { Advance(); SkipNewLines(); caseResult = Block(); if (caseResult.HasError) { return(caseResult); } cases.Add((condResult.Node, caseResult.Node)); Advance(); SkipNewLines(); } else { return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ':' or '{'"))); } } } SkipNewLines(); if (currentToken.CheckKeyword("else")) { Advance(); if (currentToken.Type == TokenType.COLON) { Advance(); SkipNewLines(); ParserResult elseResult = Expr(); if (elseResult.HasError) { return(elseResult); } elseCase = elseResult.Node; } else { SkipNewLines(); if (currentToken.Type == TokenType.LEFT_BRA) { Advance(); SkipNewLines(); ParserResult elseResult = Block(); if (elseResult.HasError) { return(elseResult); } elseCase = elseResult.Node; Advance(); SkipNewLines(); } else { return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ':' or '{'"))); } } } } else { SkipNewLines(); if (currentToken.Type == TokenType.LEFT_BRA) { Advance(); ParserResult caseResult = Block(); if (caseResult.HasError) { return(caseResult); } cases.Add((condResult.Node, caseResult.Node)); Advance(); SkipNewLines(); while (currentToken.CheckKeyword("elif")) { Advance(); condResult = Expr(); if (condResult.HasError) { return(condResult); } if (currentToken.Type == TokenType.COLON) { Advance(); SkipNewLines(); caseResult = Expr(); if (caseResult.HasError) { return(caseResult); } cases.Add((condResult.Node, caseResult.Node)); SkipNewLines(); } else { SkipNewLines(); if (currentToken.Type == TokenType.LEFT_BRA) { Advance(); SkipNewLines(); caseResult = Block(); if (caseResult.HasError) { return(caseResult); } cases.Add((condResult.Node, caseResult.Node)); Advance(); SkipNewLines(); } else { return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ':' or '{'"))); } } } SkipNewLines(); if (currentToken.CheckKeyword("else")) { Advance(); if (currentToken.Type == TokenType.COLON) { Advance(); SkipNewLines(); ParserResult elseResult = Expr(); if (elseResult.HasError) { return(elseResult); } elseCase = elseResult.Node; } else { SkipNewLines(); if (currentToken.Type == TokenType.LEFT_BRA) { Advance(); SkipNewLines(); ParserResult elseResult = Block(); if (elseResult.HasError) { return(elseResult); } elseCase = elseResult.Node; Advance(); SkipNewLines(); } else { return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ':' or '{'"))); } } } } else { return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ':' or '{'"))); } } return(new ParserResult(new IfNode(cases, elseCase).SetPosition(currentToken.Position))); }
private ParserResult Call(bool byPassDot = false) { ParserResult atomResult = Atom(byPassDot); if (atomResult.HasError) { return(atomResult); } if (currentToken.Type == TokenType.LEFT_PAREN) { Advance(); List <(string, Node)> arguments = new List <(string, Node)>(); if (currentToken.Type == TokenType.RIGHT_PAREN) { Advance(); } else { string paramName = ""; if (currentToken.Type == TokenType.IDENTIFIER && Peek().Type == TokenType.COLON) { paramName = currentToken.Value.ToString(); Advance(2); } ParserResult exprResult = Expr(); if (exprResult.HasError) { return(exprResult); } arguments.Add((paramName, exprResult.Node)); while (currentToken.Type == TokenType.COMMA) { paramName = ""; Advance(); if (currentToken.Type == TokenType.IDENTIFIER && Peek().Type == TokenType.COLON) { paramName = currentToken.Value.ToString(); Advance(2); } exprResult = Expr(); if (exprResult.HasError) { return(exprResult); } arguments.Add((paramName, exprResult.Node)); } if (currentToken.Type != TokenType.RIGHT_PAREN) { return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ')' or ','"))); } Advance(); } if (currentToken.Type == TokenType.LEFT_SQB) { return(Subscript(new CallNode(atomResult.Node, arguments).SetPosition(currentToken.Position))); } else { return(new ParserResult(new CallNode(atomResult.Node, arguments).SetPosition(currentToken.Position))); } } return(atomResult); }