public static LinkedListNode <Lexeme> TryParse(LinkedListNode <Lexeme> lexemes, out Var resultNode) { resultNode = null; if (lexemes.Value.Type != LT.IDENT) { return(lexemes); } resultNode = new Var { Token = lexemes.Value }; var nextLexeme = lexemes.Next; if (nextLexeme.Value.Type == LT.OP_SQBRACKET_O) { nextLexeme = nextLexeme.Next; nextLexeme = BinaryExpr.TryParseExpr(nextLexeme, out var expr); if (expr == null) { throw new Exception($"Opening square bracket found, but no array index at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } if (nextLexeme.Value.Type != LT.OP_SQBRACKET_C) { throw new Exception($"Missing closing square bracket after array index at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } resultNode = new ArrayVar { Token = lexemes.Value, Index = expr }; return(nextLexeme.Next); } return(nextLexeme); }
public static LinkedListNode <Lexeme> TryParse(LinkedListNode <Lexeme> lexemes, out StructLitStmt resultNode) { resultNode = null; if (lexemes.Value.Type != LT.IDENT) { return(lexemes); } var nextLexeme = lexemes.Next; if (nextLexeme.Value.Type != LT.OP_COLON) { return(lexemes); } nextLexeme = nextLexeme.Next; nextLexeme = BinaryExpr.TryParseExpr(nextLexeme, out var data); if (data != null) { resultNode = new StructLitStmt { Data = data, Token = lexemes.Value }; return(nextLexeme); } return(lexemes); }
public static LinkedListNode <Lexeme> TryParse(LinkedListNode <Lexeme> lexemes, out ReturnStmt resultNode) { resultNode = null; if (lexemes.Value.Type != LT.KW_RETURN) { return(lexemes); } var nextLexeme = lexemes.Next; nextLexeme = BinaryExpr.TryParseExpr(nextLexeme, out Expr expr); if (nextLexeme.Value.Type != LT.OP_SC) { throw new Exception($"Missing semicolon after return statement at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } resultNode = new ReturnStmt { Value = expr, Token = nextLexeme.Value }; nextLexeme = nextLexeme.Next; 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 ArrayLit resultNode) { List <Expr> exprs = new List <Expr>(); resultNode = null; if (lexemes.Value.Type != LT.OP_BRACE_O) { return(lexemes); } LinkedListNode <Lexeme> nextLexeme = lexemes.Next; nextLexeme = BinaryExpr.TryParseExpr(nextLexeme, out var expr); if (expr == null) { resultNode = new ArrayLit { Data = exprs, Token = nextLexeme.Value }; return(nextLexeme); } exprs.Add(expr); while (nextLexeme.Value.Type == LT.OP_COMMA) { nextLexeme = nextLexeme.Next; nextLexeme = BinaryExpr.TryParseExpr(nextLexeme, out expr); if (expr == null) { break; } exprs.Add(expr); } resultNode = new ArrayLit { Data = exprs, Token = nextLexeme.Value }; if (nextLexeme.Value.Type == LT.OP_BRACE_C) { nextLexeme = nextLexeme.Next; } else { throw new ArgumentException($"Missing closing brace at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } return(nextLexeme); }
public static LinkedListNode <Lexeme> TryParse(LinkedListNode <Lexeme> lexemes, out WhileLoop resultNode) { resultNode = null; if (lexemes.Value.Type != LT.KW_IF) { return(lexemes); } var nextLexeme = lexemes.Next; if (nextLexeme.Value.Type != LT.OP_PAREN_O) { throw new Exception($"Missing if condition at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } Lexeme token = nextLexeme.Value; nextLexeme = BinaryExpr.TryParseExpr(nextLexeme, out Expr expr); if (expr == null) { throw new Exception($"Cannot parse if condition at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } if (nextLexeme.Value.Type != LT.OP_PAREN_C) { throw new Exception($"Missing closing parenthesis for if condition at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; Stmt stmt; List <Stmt> stmts = new List <Stmt>(); if (nextLexeme.Value.Type == LT.OP_BRACE_O) { // block body nextLexeme = nextLexeme.Next; nextLexeme = Stmt.TryParse(nextLexeme, out stmt); while (stmt != null) { stmts.Add(stmt); nextLexeme = Stmt.TryParse(nextLexeme, out stmt); } if (nextLexeme.Value.Type != LT.OP_BRACE_C) { throw new Exception($"Missing closing bracket for while loop body at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; } else { // single statement body nextLexeme = Stmt.TryParse(nextLexeme, out stmt); if (stmt == null) { throw new Exception($"Missing while loop body at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } stmts.Add(stmt); } resultNode = new WhileLoop { Condition = expr, Body = new BlockBody(stmts), Token = token }; return(nextLexeme); }
public static LinkedListNode <Lexeme> TryParse(LinkedListNode <Lexeme> lexemes, out ForLoop resultNode) { resultNode = null; if (lexemes.Value.Type != LT.KW_FOR) { return(lexemes); } var nextLexeme = lexemes.Next; if (nextLexeme.Value.Type != LT.OP_PAREN_O) { throw new Exception($"Missing loop header at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; nextLexeme = DeclStmt.TryParse(nextLexeme, out DeclStmt ds); if (ds == null || !(ds is DeclAssignStmt init)) { throw new Exception($"Cannot parse loop initializer at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = BinaryExpr.TryParseExpr(nextLexeme, out Expr cond); if (cond == null) { throw new Exception($"Cannot parse loop condition at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } if (nextLexeme.Value.Type != LT.OP_SC) { throw new Exception($"Missing semicolon after loop condition at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; nextLexeme = AssignStmt.TryParse(nextLexeme, out AssignStmt upd, false); if (upd == null) { throw new Exception($"Cannot parse loop afterthought at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } if (nextLexeme.Value.Type != LT.OP_PAREN_C) { throw new Exception($"Missing closing parenthesis for loop header at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; Stmt stmt; List <Stmt> stmts = new List <Stmt>(); if (nextLexeme.Value.Type == LT.OP_BRACE_O) { // block body nextLexeme = nextLexeme.Next; nextLexeme = Stmt.TryParse(nextLexeme, out stmt); while (stmt != null) { stmts.Add(stmt); nextLexeme = Stmt.TryParse(nextLexeme, out stmt); } if (nextLexeme.Value.Type != LT.OP_BRACE_C) { throw new Exception($"Missing closing bracket for loop body at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; } else { // single statement body nextLexeme = Stmt.TryParse(nextLexeme, out stmt); if (stmt == null) { throw new Exception($"Missing loop body at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } stmts.Add(stmt); } resultNode = new ForLoop { Init = init, Condition = cond, Update = upd, Body = new BlockBody(stmts) }; return(nextLexeme); }
public static LinkedListNode <Lexeme> TryParse(LinkedListNode <Lexeme> lexemes, out IfStmt resultNode) { resultNode = null; if (lexemes.Value.Type != LT.KW_IF) { return(lexemes); } var nextLexeme = lexemes.Next; if (nextLexeme.Value.Type != LT.OP_PAREN_O) { throw new Exception($"Missing if condition at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = BinaryExpr.TryParseExpr(nextLexeme.Next, out Expr expr); if (expr == null) { throw new Exception($"Cannot parse if condition at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } if (nextLexeme.Value.Type != LT.OP_PAREN_C) { throw new Exception($"Missing closing parenthesis for if condition at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; Stmt stmt; List <Stmt> stmts = new List <Stmt>(); bool elseAllowed = true; if (nextLexeme.Value.Type == LT.OP_BRACE_O) { // block body nextLexeme = nextLexeme.Next; nextLexeme = Stmt.TryParse(nextLexeme, out stmt); while (stmt != null) { stmts.Add(stmt); nextLexeme = Stmt.TryParse(nextLexeme, out stmt); } if (nextLexeme.Value.Type != LT.OP_BRACE_C) { throw new Exception($"Missing closing bracket for if body at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; } else { // single statement body nextLexeme = Stmt.TryParse(nextLexeme, out stmt); if (stmt == null) { throw new Exception($"Missing if body at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } stmts.Add(stmt); if (stmt is IfStmt) { elseAllowed = false; } } if (elseAllowed) { if (nextLexeme.Value.Type == LT.KW_ELSE) { List <Stmt> elseStmts = new List <Stmt>(); nextLexeme = nextLexeme.Next; if (nextLexeme.Value.Type == LT.OP_BRACE_O) { // block body nextLexeme = nextLexeme.Next; nextLexeme = Stmt.TryParse(nextLexeme, out stmt); while (stmt != null) { elseStmts.Add(stmt); nextLexeme = Stmt.TryParse(nextLexeme, out stmt); } if (nextLexeme.Value.Type != LT.OP_BRACE_C) { throw new Exception($"Missing closing bracket for else body at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } nextLexeme = nextLexeme.Next; } else { // single statement body nextLexeme = Stmt.TryParse(nextLexeme, out stmt); if (stmt == null) { throw new Exception($"Missing else body at {nextLexeme.Value.File}:{nextLexeme.Value.Line}"); } elseStmts.Add(stmt); } resultNode = new IfStmt { Condition = expr, Body = new BlockBody(stmts), ElseBody = new BlockBody(elseStmts), Token = lexemes.Value }; return(nextLexeme); } } resultNode = new IfStmt { Condition = expr, Body = new BlockBody(stmts), ElseBody = null, Token = lexemes.Value }; return(nextLexeme); }