/// <summary> /// Creates a sub tree of binary expressions /// </summary> private static Expression CreateSubTree(LinkedList list, ScriptLoadingContext lcontext) { var opfound = list.OperatorMask; var nodes = list.Nodes; if ((opfound & POWER) != 0) nodes = PrioritizeRightAssociative(nodes, lcontext, POWER); if ((opfound & MUL_DIV_MOD) != 0) nodes = PrioritizeLeftAssociative(nodes, lcontext, MUL_DIV_MOD); if ((opfound & ADD_SUB) != 0) nodes = PrioritizeLeftAssociative(nodes, lcontext, ADD_SUB); if ((opfound & STRCAT) != 0) nodes = PrioritizeRightAssociative(nodes, lcontext, STRCAT); if ((opfound & COMPARES) != 0) nodes = PrioritizeLeftAssociative(nodes, lcontext, COMPARES); if ((opfound & LOGIC_AND) != 0) nodes = PrioritizeLeftAssociative(nodes, lcontext, LOGIC_AND); if ((opfound & LOGIC_OR) != 0) nodes = PrioritizeLeftAssociative(nodes, lcontext, LOGIC_OR); if (nodes.Next != null || nodes.Prev != null) throw new InternalErrorException("Expression reduction didn't work! - 1"); if (nodes.Expr == null) throw new InternalErrorException("Expression reduction didn't work! - 2"); return nodes.Expr; }
public LiteralExpression(ScriptLoadingContext lcontext, Token t) : base(lcontext) { switch (t.Type) { case TokenType.Number: case TokenType.Number_Hex: case TokenType.Number_HexFloat: Value = DynValue.NewNumber(t.GetNumberValue()).AsReadOnly(); break; case TokenType.String: case TokenType.String_Long: Value = DynValue.NewString(t.Text).AsReadOnly(); break; case TokenType.True: Value = DynValue.True; break; case TokenType.False: Value = DynValue.False; break; case TokenType.Nil: Value = DynValue.Nil; break; default: throw new InternalErrorException("type mismatch"); } if (Value == null) throw new SyntaxErrorException(t, "unknown literal format near '{0}'", t.Text); lcontext.Lexer.Next(); }
public ReturnStatement(ScriptLoadingContext lcontext, Expression e, SourceRef sref) : base(lcontext) { m_Expression = e; m_Ref = sref; lcontext.Source.Refs.Add(sref); }
public ForLoopStatement(ScriptLoadingContext lcontext, Token nameToken, Token forToken) : base(lcontext) { // for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end | // lexer already at the '=' ! [due to dispatching vs for-each] CheckTokenType(lcontext, TokenType.Op_Assignment); m_Start = Expression.Expr(lcontext); CheckTokenType(lcontext, TokenType.Comma); m_End = Expression.Expr(lcontext); if (lcontext.Lexer.Current.Type == TokenType.Comma) { lcontext.Lexer.Next(); m_Step = Expression.Expr(lcontext); } else { m_Step = new LiteralExpression(lcontext, DynValue.NewNumber(1)); } lcontext.Scope.PushBlock(); m_VarName = lcontext.Scope.DefineLocal(nameToken.Text); m_RefFor = forToken.GetSourceRef(CheckTokenType(lcontext, TokenType.Do)); m_InnerBlock = new CompositeStatement(lcontext); m_RefEnd = CheckTokenType(lcontext, TokenType.End).GetSourceRef(); m_StackFrame = lcontext.Scope.PopBlock(); lcontext.Source.Refs.Add(m_RefFor); lcontext.Source.Refs.Add(m_RefEnd); }
private BinaryOperatorExpression(Expression exp1, Expression exp2, Operator op, ScriptLoadingContext lcontext) : base(lcontext) { m_Exp1 = exp1; m_Exp2 = exp2; m_Operator = op; }
private Statement CreateLambdaBody(ScriptLoadingContext lcontext) { Token start = lcontext.Lexer.Current; Expression e = Expression.Expr(lcontext); Token end = lcontext.Lexer.Current; SourceRef sref = start.GetSourceRefUpTo(end); Statement s = new ReturnStatement(lcontext, e, sref); return s; }
private IVariable CheckVar(ScriptLoadingContext lcontext, Expression firstExpression) { IVariable v = firstExpression as IVariable; if (v == null) throw new SyntaxErrorException(lcontext.Lexer.Current, "unexpected symbol near '{0}' - not a l-value", lcontext.Lexer.Current); return v; }
public SymbolRefExpression(ScriptLoadingContext lcontext, SymbolRef refr) : base(lcontext) { m_Ref = refr; if (lcontext.IsDynamicExpression) { throw new DynamicExpressionException("Unsupported symbol reference expression detected."); } }
protected static Token CheckTokenType(ScriptLoadingContext lcontext, TokenType tokenType1, TokenType tokenType2) { var t = lcontext.Lexer.Current; if (t.Type != tokenType1 && t.Type != tokenType2) return UnexpectedTokenType(t); lcontext.Lexer.Next(); return t; }
private void StructField(ScriptLoadingContext lcontext) { Expression key = new LiteralExpression(lcontext, DynValue.NewString(lcontext.Lexer.Current.Text)); lcontext.Lexer.Next(); CheckTokenType(lcontext, TokenType.Op_Assignment); var value = Expr(lcontext); m_CtorArgs.Add(new KeyValuePair<Expression, Expression>(key, value)); }
public LabelStatement(ScriptLoadingContext lcontext) : base(lcontext) { CheckTokenType(lcontext, TokenType.DoubleColon); NameToken = CheckTokenType(lcontext, TokenType.Name); CheckTokenType(lcontext, TokenType.DoubleColon); SourceRef = NameToken.GetSourceRef(); Label = NameToken.Text; lcontext.Scope.DefineLabel(this); }
public GotoStatement(ScriptLoadingContext lcontext) : base(lcontext) { GotoToken = CheckTokenType(lcontext, TokenType.Goto); var name = CheckTokenType(lcontext, TokenType.Name); SourceRef = GotoToken.GetSourceRef(name); Label = name.Text; lcontext.Scope.RegisterGoto(this); }
protected static Statement CreateStatement(ScriptLoadingContext lcontext, out bool forceLast) { Token tkn = lcontext.Lexer.Current; forceLast = false; switch (tkn.Type) { case TokenType.DoubleColon: return new LabelStatement(lcontext); case TokenType.Goto: return new GotoStatement(lcontext); case TokenType.SemiColon: lcontext.Lexer.Next(); return new EmptyStatement(lcontext); case TokenType.If: return new IfStatement(lcontext); case TokenType.While: return new WhileStatement(lcontext); case TokenType.Do: return new ScopeBlockStatement(lcontext); case TokenType.For: return DispatchForLoopStatement(lcontext); case TokenType.Repeat: return new RepeatStatement(lcontext); case TokenType.Function: return new FunctionDefinitionStatement(lcontext, false, null); case TokenType.Local: Token localToken = lcontext.Lexer.Current; lcontext.Lexer.Next(); if (lcontext.Lexer.Current.Type == TokenType.Function) return new FunctionDefinitionStatement(lcontext, true, localToken); else return new AssignmentStatement(lcontext, localToken); case TokenType.Return: forceLast = true; return new ReturnStatement(lcontext); case TokenType.Break: return new BreakStatement(lcontext); default: { Token l = lcontext.Lexer.Current; Expression exp = Expression.PrimaryExp(lcontext); FunctionCallExpression fnexp = exp as FunctionCallExpression; if (fnexp != null) return new FunctionCallStatement(lcontext, fnexp); else return new AssignmentStatement(lcontext, exp, l); } } }
IfBlock CreateElseBlock(ScriptLoadingContext lcontext) { Token type = CheckTokenType(lcontext, TokenType.Else); lcontext.Scope.PushBlock(); var ifblock = new IfBlock(); ifblock.Block = new CompositeStatement(lcontext); ifblock.StackFrame = lcontext.Scope.PopBlock(); ifblock.Source = type.GetSourceRef(); lcontext.Source.Refs.Add(ifblock.Source); return ifblock; }
public FunctionCallExpression(ScriptLoadingContext lcontext, Expression function, Token thisCallName) : base(lcontext) { Token callToken = thisCallName ?? lcontext.Lexer.Current; m_Name = thisCallName != null ? thisCallName.Text : null; m_DebugErr = function.GetFriendlyDebugName(); m_Function = function; switch (lcontext.Lexer.Current.Type) { case TokenType.Brk_Open_Round: Token openBrk = lcontext.Lexer.Current; lcontext.Lexer.Next(); Token t = lcontext.Lexer.Current; if (t.Type == TokenType.Brk_Close_Round) { m_Arguments = new List<Expression>(); SourceRef = callToken.GetSourceRef(t); lcontext.Lexer.Next(); } else { m_Arguments = ExprList(lcontext); SourceRef = callToken.GetSourceRef(CheckMatch(lcontext, openBrk, TokenType.Brk_Close_Round, ")")); } break; case TokenType.String: case TokenType.String_Long: { m_Arguments = new List<Expression>(); Expression le = new LiteralExpression(lcontext, lcontext.Lexer.Current); m_Arguments.Add(le); SourceRef = callToken.GetSourceRef(lcontext.Lexer.Current); } break; case TokenType.Brk_Open_Curly: case TokenType.Brk_Open_Curly_Shared: { m_Arguments = new List<Expression>(); m_Arguments.Add(new TableConstructor(lcontext, lcontext.Lexer.Current.Type == TokenType.Brk_Open_Curly_Shared)); SourceRef = callToken.GetSourceRefUpTo(lcontext.Lexer.Current); } break; default: throw new SyntaxErrorException(lcontext.Lexer.Current, "function arguments expected") { IsPrematureStreamTermination = (lcontext.Lexer.Current.Type == TokenType.Eof) }; } }
public ChunkStatement(ScriptLoadingContext lcontext) : base(lcontext) { lcontext.Scope.PushFunction(this, true); m_Env = lcontext.Scope.DefineLocal(WellKnownSymbols.ENV); m_VarArgs = lcontext.Scope.DefineLocal(WellKnownSymbols.VARARGS); m_Block = new CompositeStatement(lcontext); if (lcontext.Lexer.Current.Type != TokenType.Eof) throw new SyntaxErrorException(lcontext.Lexer.Current, "<eof> expected near '{0}'", lcontext.Lexer.Current.Text); m_StackFrame = lcontext.Scope.PopFunction(); }
internal static List<Expression> ExprListAfterFirstExpr(ScriptLoadingContext lcontext, Expression expr1) { List<Expression> exps = new List<Expression>(); exps.Add(expr1); while ((lcontext.Lexer.Current.Type == TokenType.Comma)) { lcontext.Lexer.Next(); exps.Add(Expr(lcontext)); } return exps; }
private static Statement DispatchForLoopStatement(ScriptLoadingContext lcontext) { // for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end | // for namelist in explist do block end | Token forTkn = CheckTokenType(lcontext, TokenType.For); Token name = CheckTokenType(lcontext, TokenType.Name); if (lcontext.Lexer.Current.Type == TokenType.Op_Assignment) return new ForLoopStatement(lcontext, name, forTkn); else return new ForEachLoopStatement(lcontext, name, forTkn); }
private void MapField(ScriptLoadingContext lcontext) { lcontext.Lexer.Next(); // skip '[' var key = Expr(lcontext); CheckTokenType(lcontext, TokenType.Brk_Close_Square); CheckTokenType(lcontext, TokenType.Op_Assignment); var value = Expr(lcontext); m_CtorArgs.Add(new KeyValuePair<Expression, Expression>(key, value)); }
public ScopeBlockStatement(ScriptLoadingContext lcontext) : base(lcontext) { lcontext.Scope.PushBlock(); m_Do = CheckTokenType(lcontext, TokenType.Do).GetSourceRef(); m_Block = new CompositeStatement(lcontext); m_End = CheckTokenType(lcontext, TokenType.End).GetSourceRef(); m_StackFrame = lcontext.Scope.PopBlock(); lcontext.Source.Refs.Add(m_Do); lcontext.Source.Refs.Add(m_End); }
internal static List<Expression> ExprList(ScriptLoadingContext lcontext) { List<Expression> exps = new List<Expression>(); while (true) { exps.Add(Expr(lcontext)); if (lcontext.Lexer.Current.Type != TokenType.Comma) break; lcontext.Lexer.Next(); } return exps; }
public IfStatement(ScriptLoadingContext lcontext) : base(lcontext) { while (lcontext.Lexer.Current.Type != TokenType.Else && lcontext.Lexer.Current.Type != TokenType.End) { m_Ifs.Add(CreateIfBlock(lcontext)); } if (lcontext.Lexer.Current.Type == TokenType.Else) { m_Else = CreateElseBlock(lcontext); } m_End = CheckTokenType(lcontext, TokenType.End).GetSourceRef(); lcontext.Source.Refs.Add(m_End); }
private IfBlock CreateIfBlock(ScriptLoadingContext lcontext) { var type = CheckTokenType(lcontext, TokenType.If, TokenType.ElseIf); lcontext.Scope.PushBlock(); var ifblock = new IfBlock(); ifblock.Exp = Expression.Expr(lcontext); ifblock.Source = type.GetSourceRef(CheckTokenType(lcontext, TokenType.Then)); ifblock.Block = new CompositeStatement(lcontext); ifblock.StackFrame = lcontext.Scope.PopBlock(); lcontext.Source.Refs.Add(ifblock.Source); return ifblock; }
protected static Token CheckMatch(ScriptLoadingContext lcontext, Token originalToken, TokenType expectedTokenType, string expectedTokenText) { Token t = lcontext.Lexer.Current; if (t.Type != expectedTokenType) { throw new SyntaxErrorException(lcontext.Lexer.Current, "'{0}' expected (to close '{1}' at line {2}) near '{3}'", expectedTokenText, originalToken.Text, originalToken.FromLine, t.Text) { IsPrematureStreamTermination = (t.Type == TokenType.Eof) }; } lcontext.Lexer.Next(); return t; }
public RepeatStatement(ScriptLoadingContext lcontext) : base(lcontext) { m_Repeat = CheckTokenType(lcontext, TokenType.Repeat).GetSourceRef(); lcontext.Scope.PushBlock(); m_Block = new CompositeStatement(lcontext); var until = CheckTokenType(lcontext, TokenType.Until); m_Condition = Expression.Expr(lcontext); m_Until = until.GetSourceRefUpTo(lcontext.Lexer.Current); m_StackFrame = lcontext.Scope.PopBlock(); lcontext.Source.Refs.Add(m_Repeat); lcontext.Source.Refs.Add(m_Until); }
public TableConstructor(ScriptLoadingContext lcontext, bool shared) : base(lcontext) { m_Shared = shared; // here lexer is at the '{', go on CheckTokenType(lcontext, TokenType.Brk_Open_Curly, TokenType.Brk_Open_Curly_Shared); while (lcontext.Lexer.Current.Type != TokenType.Brk_Close_Curly) { switch (lcontext.Lexer.Current.Type) { case TokenType.Name: { Token assign = lcontext.Lexer.PeekNext(); if (assign.Type == TokenType.Op_Assignment) StructField(lcontext); else ArrayField(lcontext); } break; case TokenType.Brk_Open_Square: MapField(lcontext); break; default: ArrayField(lcontext); break; } Token curr = lcontext.Lexer.Current; if (curr.Type == TokenType.Comma || curr.Type == TokenType.SemiColon) { lcontext.Lexer.Next(); } else { break; } } CheckTokenType(lcontext, TokenType.Brk_Close_Curly); }
public AssignmentStatement(ScriptLoadingContext lcontext, Expression firstExpression, Token first) : base(lcontext) { m_LValues.Add(CheckVar(lcontext, firstExpression)); while (lcontext.Lexer.Current.Type == TokenType.Comma) { lcontext.Lexer.Next(); var e = Expression.PrimaryExp(lcontext); m_LValues.Add(CheckVar(lcontext, e)); } CheckTokenType(lcontext, TokenType.Op_Assignment); m_RValues = Expression.ExprList(lcontext); var last = lcontext.Lexer.Current; m_Ref = first.GetSourceRefUpTo(last); lcontext.Source.Refs.Add(m_Ref); }
public CompositeStatement(ScriptLoadingContext lcontext) : base(lcontext) { while (true) { Token t = lcontext.Lexer.Current; if (t.IsEndOfBlock()) break; bool forceLast; Statement s = Statement.CreateStatement(lcontext, out forceLast); m_Statements.Add(s); if (forceLast) break; } // eat away all superfluos ';'s while (lcontext.Lexer.Current.Type == TokenType.SemiColon) lcontext.Lexer.Next(); }
public ForEachLoopStatement(ScriptLoadingContext lcontext, Token firstNameToken, Token forToken) : base(lcontext) { // for namelist in explist do block end | List<string> names = new List<string>(); names.Add(firstNameToken.Text); while (lcontext.Lexer.Current.Type == TokenType.Comma) { lcontext.Lexer.Next(); Token name = CheckTokenType(lcontext, TokenType.Name); names.Add(name.Text); } CheckTokenType(lcontext, TokenType.In); m_RValues = new ExprListExpression(Expression.ExprList(lcontext), lcontext); lcontext.Scope.PushBlock(); m_Names = names .Select(n => lcontext.Scope.TryDefineLocal(n)) .ToArray(); m_NameExps = m_Names .Select(s => new SymbolRefExpression(lcontext, s)) .Cast<IVariable>() .ToArray(); m_RefFor = forToken.GetSourceRef(CheckTokenType(lcontext, TokenType.Do)); m_Block = new CompositeStatement(lcontext); m_RefEnd = CheckTokenType(lcontext, TokenType.End).GetSourceRef(); m_StackFrame = lcontext.Scope.PopBlock(); lcontext.Source.Refs.Add(m_RefFor); lcontext.Source.Refs.Add(m_RefEnd); }
public WhileStatement(ScriptLoadingContext lcontext) : base(lcontext) { Token whileTk = CheckTokenType(lcontext, TokenType.While); m_Condition = Expression.Expr(lcontext); m_Start = whileTk.GetSourceRefUpTo(lcontext.Lexer.Current); //m_Start = BuildSourceRef(context.Start, exp.Stop); //m_End = BuildSourceRef(context.Stop, context.END()); lcontext.Scope.PushBlock(); CheckTokenType(lcontext, TokenType.Do); m_Block = new CompositeStatement(lcontext); m_End = CheckTokenType(lcontext, TokenType.End).GetSourceRef(); m_StackFrame = lcontext.Scope.PopBlock(); lcontext.Source.Refs.Add(m_Start); lcontext.Source.Refs.Add(m_End); }