/// <summary> /// Parses a block by first pushing symbol scope and then popping after completion. /// </summary> public virtual void ParseBlock(BlockExpr stmt) { this.Ctx.Symbols.Push(new SymbolsNested(string.Empty), true); stmt.SymScope = this.Ctx.Symbols.Current; _parser.ParseBlock(stmt); this.Ctx.Symbols.Pop(); }
/// <summary> /// Barses a block of code. /// </summary> /// <param name="block"></param> /// <returns></returns> public IBlockExpr ParseBlock(IBlockExpr block) { // { statemnt1; statement2; } bool isMultiLine = false; // Check for single line block if (_tokenIt.NextToken.Token == Tokens.NewLine) _tokenIt.Advance(); if (_tokenIt.NextToken.Token == Tokens.LeftBrace) isMultiLine = true; if (block == null) block = new BlockExpr(); // Case 1: Single line block. if (!isMultiLine) { var stmt = ParseStatement(); stmt.Parent = block as AstNode; block.Statements.Add(stmt); return block; } // Case 2: Multi-line block _tokenIt.Expect(Tokens.LeftBrace); while (true) { // Check for end of statment or invalid end of script. if (IsEndOfStatementOrEndOfScript(Tokens.RightBrace)) break; // New line? if (_tokenIt.NextToken.Token == Tokens.NewLine) { _tokenIt.Advance(); continue; } var stmt = ParseStatement(); if (stmt != null) { stmt.Parent = block as AstNode; block.Statements.Add(stmt); } } Expect(Tokens.RightBrace); return block; }
/// <summary> /// Executes the block with callback/template methods. /// </summary> public object VisitBlock(BlockExpr expr) { object result = LObjects.Null; try { //expr.OnBlockEnter(); expr.Ctx.Memory.Push(); LangHelper.Evaluate(expr.Statements, expr.Parent, this); } finally { //expr.OnBlockExit(); expr.Ctx.Memory.Pop(); } return result; }
public Expr OnParseIf() { var tokenIt = this._parser.TokenIt; var initiatorToken = tokenIt.NextToken; var expr = new IfExpr(); // <codeIf> tokenIt.Expect(Tokens.If); // Parse the if this.ParseConditionalBlock(expr); tokenIt.AdvancePastNewLines(); // Handle "else if" and/or else if (tokenIt.NextToken.Token == Tokens.Else) { // tokenIt.NextToken = "else" tokenIt.Advance(); tokenIt.AdvancePastNewLines(); // What's after else? // 1. "if" = else if statement // 2. "{" = multi line else // 3. "nothing" = single line else // Peek 2nd token for else if. var token = tokenIt.NextToken; if (tokenIt.NextToken.Token == Tokens.If) { expr.Else = OnParseIf() as BlockExpr; } else // Multi-line or single line else { var elseStmt = new BlockExpr(); this._parser.ParseBlock(elseStmt); this._parser.SetupContext(elseStmt, token); expr.Else = elseStmt; } } // </codeIf> this._parser.SetupContext(expr, initiatorToken); return expr; }
/// <summary> /// Parses a block by first pushing symbol scope and then popping after completion. /// </summary> public void OnParseFunctionDeclareBlock(BlockExpr expr) { var fs = expr as FunctionExpr; var funcName = fs.Meta.Name; // 1. Define the function in global symbol scope var funcSymbol = new SymbolFunction(fs.Meta); funcSymbol.FuncExpr = expr; this._parser.Context.Symbols.Define(funcSymbol); // 2. Define the aliases. if (fs.Meta.Aliases != null && fs.Meta.Aliases.Count > 0) foreach (var alias in fs.Meta.Aliases) this._parser.Context.Symbols.DefineAlias(alias, fs.Meta.Name); // 3. Push the current scope. expr.SymScope = this._parser.Context.Symbols.Current; this._parser.Context.Symbols.Push(new SymbolsFunction(fs.Meta.Name), true); // 4. Register the parameter names in the symbol scope. if( fs.Meta.Arguments != null && fs.Meta.Arguments.Count > 0) foreach(var arg in fs.Meta.Arguments) this._parser.Context.Symbols.DefineVariable(arg.Name, LTypes.Object); this._parser.ParseBlock(expr); this._parser.Context.Symbols.Pop(); }
/// <summary> /// run step 123. /// </summary> /// <returns></returns> public override Expr Parse() { // Move past "mod" _tokenIt.Advance(); // Get the name of the module "e.g." "math" var name = _tokenIt.ExpectId(); // 1. Create the symbol to represent module var symbol = new SymbolModule(); symbol.Name = name; symbol.Category = SymbolCategory.Module; symbol.DataType = new LModuleType(); symbol.DataType.Name = name; symbol.DataType.FullName = name; symbol.Scope = new SymbolsNested(name); symbol.ParentScope = this.Ctx.Symbols.Current; // 2. Add the module symbol to the current scope this.Ctx.Symbols.Define(symbol); // 3. Now push the scope on top of the current scope. ( since modules can be nested ) this.Ctx.Symbols.Push(symbol.Scope, true); var block = new BlockExpr(); _parser.ParseBlock(block); this.Ctx.Symbols.Pop(); return block; }
public object VisitBlock(BlockExpr expr) { foreach (var stmt in expr.Statements) { stmt.Visit(this); } return null; }