/// <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;
        }
Пример #2
0
        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();
        }
Пример #3
0
		public ReturnStatement(ScriptLoadingContext lcontext, Expression e, SourceRef sref)
			: base(lcontext)
		{
			m_Expression = e;
			m_Ref = sref;
			lcontext.Source.Refs.Add(sref);
		}
Пример #4
0
		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;
		}
Пример #7
0
		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;
		}
Пример #8
0
		public SymbolRefExpression(ScriptLoadingContext lcontext, SymbolRef refr)
			: base(lcontext)
		{
			m_Ref = refr;

			if (lcontext.IsDynamicExpression)
			{
				throw new DynamicExpressionException("Unsupported symbol reference expression detected.");
			}
		}
Пример #9
0
        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;
        }
Пример #10
0
        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));
        }
Пример #11
0
		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);
		}
Пример #12
0
        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);
        }
Пример #13
0
		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);
					}
			}
		}
Пример #14
0
		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;
		}
Пример #15
0
		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)
					};
			}
		}
Пример #16
0
		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();
		}
Пример #17
0
		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;
		}
Пример #18
0
		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);
		}
Пример #19
0
        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));
        }
Пример #20
0
		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);
		}
Пример #21
0
		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; 
		}
Пример #22
0
		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);
		}
Пример #23
0
        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;
        }
Пример #24
0
		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;
		}
Пример #25
0
        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);
        }
Пример #26
0
		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);
		}
Пример #27
0
        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);
        }
Пример #28
0
		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();
		}
Пример #29
0
		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);
		}
Пример #30
0
		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);
		}