private DefStatement ParseDef(Dictionary <string, int> varTable) { //Console.WriteLine(string.Join(", ", varTable.Keys)); var def = new DefStatement(_enumerator.Current.row, _enumerator.Current.column, varTable) { Name = this.Match(TokenKind.NAME).data, Args = this.MatchDefArgs() }; def.FuncList = new List <DefStatement>(_currentNameSpace.FuncList); _currentNameSpace.AddFunction(def); //def.Args.Reverse(); foreach (var arg in def.Args) { if (def.varTable.Keys.Contains(arg)) { def.varTable.Remove(arg); } //def.AddVar(arg); def.AddArg(arg); } this.Match(TokenKind.COLON); if (MatchBool(TokenKind.NEWLINE)) { var prevNameSpace = _currentNameSpace; _currentNameSpace = def; //ParseUntil(def, TokenKind.RETURN); ParseUntil(def, TokenKind.DEDENT); //Console.WriteLine(string.Join(", ", def.varTable.Keys.ToList())); //Console.WriteLine(string.Join(", ", _base.varTable.ToList())); //_enumerator.MovePrevious(); //_enumerator.MovePrevious(); //def.Return = this.MatchReturn(); //this.MatchCurrent(TokenKind.NEWLINE); //this.Match(TokenKind.DEDENT); /* * Console.WriteLine(def.Name); * foreach (var kvp in def.varTable) * { * Console.WriteLine($"{kvp.Key.ToString()} : {kvp.Value.ToString()}"); * }*/ _currentNameSpace = prevNameSpace; } else { this.MatchCurrent(TokenKind.RETURN); def.Return = ParseExpr(); MatchCurrent(TokenKind.NEWLINE); } return(def); }
private void ParseUntil(RootNode baseNode, TokenKind?stopToken = null) { while (_enumerator.MoveNext()) { var token = _enumerator.Current; if (token.Kind == stopToken) { break; } switch (token.Kind) { case TokenKind.DEF: { DefStatement temp = null; switch (baseNode) { case IVariableTableContainer tableContainer: { temp = ParseDef(new Dictionary <string, int>(tableContainer.varTable)); break; } default: { temp = ParseDef(new Dictionary <string, int>(_base.varTable)); break; } } baseNode.AddChild(temp); break; } case TokenKind.NAME: { //Console.WriteLine(_enumerator.Current.data); if (_enumerator.MoveNext()) { if (_enumerator.Current.Kind == TokenKind.EQUAL) { _enumerator.MovePrevious(); var name = _enumerator.Current.data; _enumerator.MoveNext(); _enumerator.MoveNext(); var expr = ParseExpr(); baseNode.AddChild(new AssignStatement( _enumerator.Current.row, _enumerator.Current.column, name, expr)); switch (baseNode) { case IVariableTableContainer tableContainer: { tableContainer.AddVar(name); break; } default: { _currentNameSpace.AddVar(name); break; } } } else if (_enumerator.Current.Kind == TokenKind.PLUSEQUAL || _enumerator.Current.Kind == TokenKind.MINEQUAL || _enumerator.Current.Kind == TokenKind.STAREQUAL || _enumerator.Current.Kind == TokenKind.SLASHEQUAL) { _enumerator.MovePrevious(); var name = _enumerator.Current.data; var row = _enumerator.Current.row; var col = _enumerator.Current.column; switch (baseNode) { case IVariableTableContainer tableContainer: { if (!tableContainer.HaveVariable(name)) { throw new CompilerException( $"Name {name} is not defined at {_enumerator.Current.row}:{_enumerator.Current.column}", _enumerator.Current.row, _enumerator.Current.column); } break; } default: { if (!_currentNameSpace.HaveVariable(name)) { throw new CompilerException( $"Name {name} is not defined at {_enumerator.Current.row}:{_enumerator.Current.column}", _enumerator.Current.row, _enumerator.Current.column); } break; } } _enumerator.MoveNext(); //var op = _enumerator.Current.Kind; var op = _enumerator.Current.Kind switch { TokenKind.PLUSEQUAL => TokenKind.PLUS, TokenKind.MINEQUAL => TokenKind.MINUS, TokenKind.STAREQUAL => TokenKind.STAR, TokenKind.SLASHEQUAL => TokenKind.SLASH }; if (_enumerator.MoveNext()) { baseNode.AddChild(new AssignStatement( _enumerator.Current.row, _enumerator.Current.column, name, new BinOp(_enumerator.Current.row, _enumerator.Current.column, op, new VarExpression(row, col, name), ParseExpr() ))); } } else if (_enumerator.Current.Kind == TokenKind.LPAR) { _enumerator.MovePrevious(); var tempEx = ParseExpr(); var temp = new ExprStatement(tempEx.Row, tempEx.Column, tempEx); //var temp = ParseName(); baseNode.AddChild(temp); // if (!_base.root.GetChildren() // .Any(def => // def is DefStatement d && // d.Name == temp.Name)) // { // throw new SyntaxException( // $"Name {temp.Name} is not defined at {temp.Row + 1}:{temp.Column}", // temp.Row, temp.Column); // } this.MatchIndentation(); break; } else { _enumerator.MovePrevious(); baseNode.AddChild(new ExprStatement( _enumerator.Current.row, _enumerator.Current.column, ParseExpr())); ; } } break; } case TokenKind.IF: { var temp = ParseConditional(); baseNode.AddChild(temp); //_enumerator.MovePrevious(); break; } case TokenKind.INT: case TokenKind.MINUS: case TokenKind.TILDE: case TokenKind.EXCLAMINATION: case TokenKind.LPAR: { var temp = new ExprStatement(_enumerator.Current.row, _enumerator.Current.column, ParseExpr()); //Console.WriteLine(temp.ToString()); baseNode.AddChild(temp); MatchIndentationCurrent(); break; } case TokenKind.WHILE: { var temp = ParseWhileLoop(); baseNode.AddChild(temp); break; } case TokenKind.BREAK: { if (_currentLoop == null) { throw new CompilerException($"Break is outside of loop at {_enumerator.Current.row}:" + $"{_enumerator.Current.column}", _enumerator.Current.row, _enumerator.Current.column); } baseNode.AddChild(new BreakStatement(_enumerator.Current.row, _enumerator.Current.column)); break; } case TokenKind.CONTINUE: { if (_currentLoop == null) { throw new CompilerException($"Continue is outside of loop at {_enumerator.Current.row}:" + $"{_enumerator.Current.column}", _enumerator.Current.row, _enumerator.Current.column); } baseNode.AddChild(new ContinueStatement(_enumerator.Current.row, _enumerator.Current.column)); break; } case TokenKind.PRINT: { var temp = new Print(_enumerator.Current.row, _enumerator.Current.column); Match(TokenKind.LPAR); temp.expr = ParseExpr(); _enumerator.MovePrevious(); MatchCurrent(TokenKind.RPAR); baseNode.AddChild(temp); break; } case TokenKind.RETURN: { if (_currentNameSpace.GetType() != typeof(DefStatement)) { throw new CompilerException($"Return outside of function at {_enumerator.Current.row}:" + $"{_enumerator.Current.column}", _enumerator.Current.row, _enumerator.Current.column); } var t = _enumerator.Current; _enumerator.MovePrevious(); baseNode.AddChild(new ReturnStatement(t.row, t.column, MatchReturn())); break; } default: { break; } } } }