public static LinkedListNode <Lexeme> TryParse(LinkedListNode <Lexeme> lexemes, out FnCall resultNode) { List <Expr> exprs = new List <Expr>(); resultNode = null; if (lexemes.Value.Type != LT.IDENT) { return(lexemes); } Lexeme token = lexemes.Value; var nextLexeme = lexemes.Next; if (nextLexeme.Value.Type != LT.OP_PAREN_O) { return(lexemes); } nextLexeme = nextLexeme.Next; nextLexeme = Expr.TryParse(nextLexeme, out Expr expr); if (expr == null) { resultNode = new FnCall { Args = exprs, Token = token }; return(nextLexeme); } exprs.Add(expr); while (nextLexeme.Value.Type == LT.OP_COMMA) { nextLexeme = nextLexeme.Next; nextLexeme = Expr.TryParse(nextLexeme, out expr); if (expr == null) { throw new Exception($"Trailing comma at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } exprs.Add(expr); } resultNode = new FnCall { Args = exprs, Token = token }; if (nextLexeme.Value.Type == LT.OP_PAREN_C) { nextLexeme = nextLexeme.Next; } else { throw new Exception($"Missing closing parenthesis at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } return(nextLexeme); }
public static LinkedListNode <Lexeme> TryParseNoLit(LinkedListNode <Lexeme> lexemes, out Expr resultNode) { Expr node = null; resultNode = null; LinkedListNode <Lexeme> nextLexeme = lexemes; if (lexemes.Value.Type == LT.OP_PAREN_O) { nextLexeme = BinaryExpr.TryParseExpr(lexemes.Next, out Expr expr); if (expr != null) { node = expr; if (nextLexeme.Value.Type != LT.OP_PAREN_C) { throw new Exception($"Missing closing parenthesis at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; } } if (node == null) { nextLexeme = FnCall.TryParse(lexemes, out FnCall fnc); node = fnc; } if (node == null) { nextLexeme = Var.TryParse(lexemes, out Var v); node = v; } if (node == null) { return(lexemes); } while (nextLexeme.Value.Type == LT.OP_PNT) { nextLexeme = Var.TryParse(nextLexeme.Next, out Var v); if (v == null) { throw new Exception($"No trailing points allowed! At {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } node = new PointExpr { Left = node, Right = v }; } resultNode = node; return(nextLexeme); }
public static LinkedListNode <Lexeme> TryParse(LinkedListNode <Lexeme> lexemes, out Stmt resultNode) { resultNode = null; if (lexemes.Value.Type == LT.OP_SC) { resultNode = new BlankStmt(); return(lexemes.Next); } var nextLexeme = IfStmt.TryParse(lexemes, out IfStmt sif); if (sif != null) { resultNode = sif; return(nextLexeme); } nextLexeme = TryParseStruct(lexemes, out Stmt stmt); if (stmt != null) { resultNode = stmt; return(nextLexeme); } nextLexeme = FnCall.TryParse(lexemes, out FnCall fnc); if (fnc != null) { if (nextLexeme.Value.Type == LT.OP_SC) { resultNode = new ExprStmt <FnCall>(fnc); return(nextLexeme.Next); } } nextLexeme = ForLoop.TryParse(lexemes, out ForLoop fl); if (fl != null) { resultNode = fl; return(nextLexeme); } nextLexeme = WhileLoop.TryParse(lexemes, out WhileLoop wl); if (wl != null) { resultNode = wl; return(nextLexeme); } nextLexeme = AssignStmt.TryParse(lexemes, out AssignStmt sa); if (sa != null) { resultNode = sa; return(nextLexeme); } nextLexeme = ReturnStmt.TryParse(lexemes, out ReturnStmt sr); if (sr != null) { resultNode = sr; return(nextLexeme); } if (lexemes.Value.Type == LT.KW_BREAK) { if (lexemes.Next.Value.Type != LT.OP_SC) { throw new Exception($"Missing semicolon after break keyword at {lexemes.Value.File}:{lexemes.Value.Line}"); } resultNode = new BreakStmt { Token = lexemes.Value }; return(lexemes.Next.Next); } if (lexemes.Value.Type == LT.KW_CONT) { if (lexemes.Next.Value.Type != LT.OP_SC) { throw new Exception($"Missing semicolon after continue keyword at {lexemes.Value.File}:{lexemes.Value.Line}"); } resultNode = new ContinueStmt { Token = lexemes.Value }; return(lexemes.Next.Next); } return(lexemes); }