Bläddra i källkod

binary ops, unary ops, exp list, indexes, funcalls exps, symrefs

Xanathar 10 år sedan
förälder
incheckning
e9bb7f19f9
26 ändrade filer med 802 tillägg och 201 borttagningar
  1. 67 0
      src/MoonSharp.Interpreter.Tests/EndToEnd/SimpleTests.cs
  2. 13 0
      src/MoonSharp.Interpreter/Execution/ScriptLoadingContext.cs
  3. 8 7
      src/MoonSharp.Interpreter/MoonSharp.Interpreter.csproj
  4. 2 1
      src/MoonSharp.Interpreter/Script.cs
  5. 2 2
      src/MoonSharp.Interpreter/Tree/ANTLR_Deprecated/ANTLR_FunctionCall.cs
  6. 9 9
      src/MoonSharp.Interpreter/Tree/ANTLR_Deprecated/ANTLR_FunctionCallChainExpression.cs
  7. 4 4
      src/MoonSharp.Interpreter/Tree/ANTLR_Deprecated/ANTLR_FunctionCallStatement.cs
  8. 0 29
      src/MoonSharp.Interpreter/Tree/Expression.cs
  9. 78 75
      src/MoonSharp.Interpreter/Tree/Expressions/BinaryOperatorExpression.cs
  10. 12 6
      src/MoonSharp.Interpreter/Tree/Expressions/ExprListExpression.cs
  11. 87 0
      src/MoonSharp.Interpreter/Tree/Expressions/FunctionCallExpression.cs
  12. 9 0
      src/MoonSharp.Interpreter/Tree/Expressions/IndexExpression.cs
  13. 63 6
      src/MoonSharp.Interpreter/Tree/Expressions/LiteralExpression.cs
  14. 7 0
      src/MoonSharp.Interpreter/Tree/Expressions/PowerOperatorExpression.cs
  15. 23 0
      src/MoonSharp.Interpreter/Tree/Expressions/SymbolRefExpression.cs
  16. 8 0
      src/MoonSharp.Interpreter/Tree/Expressions/TableConstructor.cs
  17. 9 0
      src/MoonSharp.Interpreter/Tree/Expressions/UnaryOperatorExpression.cs
  18. 83 45
      src/MoonSharp.Interpreter/Tree/Lexer/Lexer.cs
  19. 32 1
      src/MoonSharp.Interpreter/Tree/Lexer/Token.cs
  20. 7 2
      src/MoonSharp.Interpreter/Tree/Lexer/TokenType.cs
  21. 4 4
      src/MoonSharp.Interpreter/Tree/NodeFactory.cs
  22. 4 2
      src/MoonSharp.Interpreter/Tree/Statement.cs
  23. 17 7
      src/MoonSharp.Interpreter/Tree/Statements/ChunkStatement.cs
  24. 1 1
      src/MoonSharp.Interpreter/Tree/Statements/CompositeStatement.cs
  25. 18 0
      src/MoonSharp.Interpreter/Tree/Statements/ReturnStatement.cs
  26. 235 0
      src/MoonSharp.Interpreter/Tree/__Expression.cs

+ 67 - 0
src/MoonSharp.Interpreter.Tests/EndToEnd/SimpleTests.cs

@@ -61,6 +61,25 @@ namespace MoonSharp.Interpreter.Tests
 			Assert.AreEqual(DataType.Void, res.Type);
 			Assert.AreEqual(DataType.Void, res.Type);
 		}
 		}
 
 
+		[Test]
+		public void CSharpStaticFunctionCall2()
+		{
+			IList<DynValue> args = null;
+
+			string script = "return callback 'hello';";
+
+			var S = new Script();
+			S.Globals.Set("callback", DynValue.NewCallback(new CallbackFunction((_x, a) => { args = a.GetArray(); return DynValue.NewNumber(1234.0); })));
+
+			DynValue res = S.DoString(script);
+
+			Assert.AreEqual(1, args.Count);
+			Assert.AreEqual(DataType.String, args[0].Type);
+			Assert.AreEqual("hello", args[0].String);
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(1234.0, res.Number);
+		}
+
 		[Test]
 		[Test]
 		public void CSharpStaticFunctionCall()
 		public void CSharpStaticFunctionCall()
 		{
 		{
@@ -151,6 +170,7 @@ namespace MoonSharp.Interpreter.Tests
 		[Test]
 		[Test]
 		public void ParserErrorMessage()
 		public void ParserErrorMessage()
 		{
 		{
+			bool caught = false;
 			string script = @"    
 			string script = @"    
 				return 'It's a wet floor warning saying wheat flour instead. \
 				return 'It's a wet floor warning saying wheat flour instead. \
 				Probably, the cook thought it was funny. \
 				Probably, the cook thought it was funny. \
@@ -162,10 +182,25 @@ namespace MoonSharp.Interpreter.Tests
 			}
 			}
 			catch (SyntaxErrorException ex)
 			catch (SyntaxErrorException ex)
 			{
 			{
+				caught = true;
 				Assert.IsNotNullOrEmpty(ex.Message);
 				Assert.IsNotNullOrEmpty(ex.Message);
 			}
 			}
+
+			Assert.IsTrue(caught);
 		}
 		}
 
 
+		[Test]
+		public void StringsWithBackslashLineEndings2()
+		{
+			string script = @"    
+				return 'a\
+				b\
+				c'";
+
+			DynValue res = Script.RunString(script);
+
+			Assert.AreEqual(DataType.String, res.Type);
+		}
 
 
 		[Test]
 		[Test]
 		public void StringsWithBackslashLineEndings()
 		public void StringsWithBackslashLineEndings()
@@ -199,6 +234,27 @@ namespace MoonSharp.Interpreter.Tests
 		}
 		}
 
 
 
 
+		[Test]
+		public void ReturnSimpleUnop()
+		{
+			string script = @"return -42";
+
+			DynValue res = Script.RunString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(-42, res.Number);
+		}
+
+		[Test]
+		public void ReturnSimple()
+		{
+			string script = @"return 42";
+
+			DynValue res = Script.RunString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(42, res.Number);
+		}
 
 
 
 
 		[Test]
 		[Test]
@@ -622,6 +678,17 @@ namespace MoonSharp.Interpreter.Tests
 			Assert.AreEqual(12, res.Number);
 			Assert.AreEqual(12, res.Number);
 		}
 		}
 
 
+		[Test]
+		public void OperatorPrecedence6()
+		{
+			string script = @"return -2^2";
+			Script S = new Script(CoreModules.None);
+
+			DynValue res = S.DoString(script);
+
+			Assert.AreEqual(DataType.Number, res.Type);
+			Assert.AreEqual(-4, res.Number);
+		}
 
 
 
 
 		[Test]
 		[Test]

+ 13 - 0
src/MoonSharp.Interpreter/Execution/ScriptLoadingContext.cs

@@ -20,5 +20,18 @@ namespace MoonSharp.Interpreter.Execution
 		{
 		{
 			Script = s;
 			Script = s;
 		}
 		}
+
+		public void EnterLevel()
+		{
+			//if (++ls.L.nCcalls > LUAI_MAXCCALLS)
+			//	LuaXLexError(ls, "chunk has too many syntax levels", 0);
+		}
+
+		public void LeaveLevel()
+		{
+			//ls.L.nCcalls--;
+		}
+
+
 	}
 	}
 }
 }

+ 8 - 7
src/MoonSharp.Interpreter/MoonSharp.Interpreter.csproj

@@ -251,18 +251,21 @@
     <Compile Include="Tree\Antlr_Interface\AntlrErrorListener.cs" />
     <Compile Include="Tree\Antlr_Interface\AntlrErrorListener.cs" />
     <Compile Include="Tree\Expressions\AdjustmentExpression.cs" />
     <Compile Include="Tree\Expressions\AdjustmentExpression.cs" />
     <Compile Include="Tree\Expressions\BinaryOperatorExpression.cs" />
     <Compile Include="Tree\Expressions\BinaryOperatorExpression.cs" />
+    <Compile Include="Tree\ANTLR_Deprecated\ANTLR_BinaryOperatorExpression.cs" />
     <Compile Include="Tree\Expressions\DynamicExpression.cs" />
     <Compile Include="Tree\Expressions\DynamicExpression.cs" />
+    <Compile Include="Tree\Expressions\FunctionCallExpression.cs" />
     <Compile Include="Tree\Expressions\PowerOperatorExpression.cs" />
     <Compile Include="Tree\Expressions\PowerOperatorExpression.cs" />
     <Compile Include="Tree\Expressions\UnaryOperatorExpression.cs" />
     <Compile Include="Tree\Expressions\UnaryOperatorExpression.cs" />
+    <Compile Include="Tree\Fast_Interface\Loader_Fast.cs" />
     <Compile Include="Tree\IVariable.cs" />
     <Compile Include="Tree\IVariable.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Tree\Expressions\ExprListExpression.cs" />
     <Compile Include="Tree\Expressions\ExprListExpression.cs" />
     <Compile Include="Tree\Expressions\FunctionDefinitionExpression.cs" />
     <Compile Include="Tree\Expressions\FunctionDefinitionExpression.cs" />
     <Compile Include="Tree\Expressions\LiteralExpression.cs" />
     <Compile Include="Tree\Expressions\LiteralExpression.cs" />
     <Compile Include="Tree\Expressions\IndexExpression.cs" />
     <Compile Include="Tree\Expressions\IndexExpression.cs" />
-    <Compile Include="Tree\FunctionCall.cs" />
-    <Compile Include="Tree\Expressions\FunctionCallChainExpression.cs" />
-    <Compile Include="Tree\Expression.cs" />
+    <Compile Include="Tree\ANTLR_Deprecated\ANTLR_FunctionCall.cs" />
+    <Compile Include="Tree\ANTLR_Deprecated\ANTLR_FunctionCallChainExpression.cs" />
+    <Compile Include="Tree\__Expression.cs" />
     <Compile Include="Tree\Expressions\OperatorExpression.cs" />
     <Compile Include="Tree\Expressions\OperatorExpression.cs" />
     <Compile Include="Tree\Expressions\SymbolRefExpression.cs" />
     <Compile Include="Tree\Expressions\SymbolRefExpression.cs" />
     <Compile Include="Tree\Antlr_Interface\Loader_Antlr.cs" />
     <Compile Include="Tree\Antlr_Interface\Loader_Antlr.cs" />
@@ -281,7 +284,7 @@
     <Compile Include="Tree\Statements\BreakStatement.cs" />
     <Compile Include="Tree\Statements\BreakStatement.cs" />
     <Compile Include="Tree\Statements\ForEachLoopStatement.cs" />
     <Compile Include="Tree\Statements\ForEachLoopStatement.cs" />
     <Compile Include="Tree\Statements\ForLoopStatement.cs" />
     <Compile Include="Tree\Statements\ForLoopStatement.cs" />
-    <Compile Include="Tree\Statements\FunctionCallStatement.cs" />
+    <Compile Include="Tree\ANTLR_Deprecated\ANTLR_FunctionCallStatement.cs" />
     <Compile Include="Tree\Statements\FunctionDefinitionStatement.cs" />
     <Compile Include="Tree\Statements\FunctionDefinitionStatement.cs" />
     <Compile Include="Tree\Statements\IfStatement.cs" />
     <Compile Include="Tree\Statements\IfStatement.cs" />
     <Compile Include="Tree\Statement.cs" />
     <Compile Include="Tree\Statement.cs" />
@@ -306,9 +309,7 @@
   <ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />
     <None Include="packages.config" />
   </ItemGroup>
   </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Tree\Fast_Interface\" />
-  </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
     <PropertyGroup>

+ 2 - 1
src/MoonSharp.Interpreter/Script.cs

@@ -15,6 +15,7 @@ using MoonSharp.Interpreter.IO;
 using MoonSharp.Interpreter.Loaders;
 using MoonSharp.Interpreter.Loaders;
 using MoonSharp.Interpreter.Tree;
 using MoonSharp.Interpreter.Tree;
 using MoonSharp.Interpreter.Tree.Expressions;
 using MoonSharp.Interpreter.Tree.Expressions;
+using MoonSharp.Interpreter.Tree.Fast_Interface;
 using MoonSharp.Interpreter.Tree.Statements;
 using MoonSharp.Interpreter.Tree.Statements;
 
 
 namespace MoonSharp.Interpreter
 namespace MoonSharp.Interpreter
@@ -171,7 +172,7 @@ namespace MoonSharp.Interpreter
 
 
 			m_Sources.Add(source);
 			m_Sources.Add(source);
 
 
-			int address = Loader_Antlr.LoadChunk(this,
+			int address = Loader_Fast.LoadChunk(this,
 				source,
 				source,
 				m_ByteCode,
 				m_ByteCode,
 				globalTable ?? m_GlobalTable);
 				globalTable ?? m_GlobalTable);

+ 2 - 2
src/MoonSharp.Interpreter/Tree/FunctionCall.cs → src/MoonSharp.Interpreter/Tree/ANTLR_Deprecated/ANTLR_FunctionCall.cs

@@ -10,13 +10,13 @@ using MoonSharp.Interpreter.Tree.Expressions;
 
 
 namespace MoonSharp.Interpreter.Tree
 namespace MoonSharp.Interpreter.Tree
 {
 {
-	class FunctionCall : NodeBase
+	class ANTLR_FunctionCall : NodeBase
 	{
 	{
 		Expression[] m_Arguments;
 		Expression[] m_Arguments;
 		string m_Name;
 		string m_Name;
 		string m_DebugErr;
 		string m_DebugErr;
 
 
-		public FunctionCall(LuaParser.NameAndArgsContext nameAndArgs, ScriptLoadingContext lcontext)
+		public ANTLR_FunctionCall(LuaParser.NameAndArgsContext nameAndArgs, ScriptLoadingContext lcontext)
 			: base(nameAndArgs, lcontext)
 			: base(nameAndArgs, lcontext)
 		{
 		{
 			var name = nameAndArgs.NAME();
 			var name = nameAndArgs.NAME();

+ 9 - 9
src/MoonSharp.Interpreter/Tree/Expressions/FunctionCallChainExpression.cs → src/MoonSharp.Interpreter/Tree/ANTLR_Deprecated/ANTLR_FunctionCallChainExpression.cs

@@ -9,33 +9,33 @@ using MoonSharp.Interpreter.Grammar;
 
 
 namespace MoonSharp.Interpreter.Tree.Expressions
 namespace MoonSharp.Interpreter.Tree.Expressions
 {
 {
-	class FunctionCallChainExpression : Expression
+	class ANTLR_FunctionCallChainExpression : Expression
 	{
 	{
 		Expression m_StartingExpression;
 		Expression m_StartingExpression;
-		List<FunctionCall> m_CallChain;
+		List<ANTLR_FunctionCall> m_CallChain;
 
 
-		private FunctionCallChainExpression(IParseTree context, ScriptLoadingContext lcontext, 
+		private ANTLR_FunctionCallChainExpression(IParseTree context, ScriptLoadingContext lcontext, 
 			LuaParser.VarOrExpContext varOrExp, IEnumerable<LuaParser.NameAndArgsContext> nameAndArgs)
 			LuaParser.VarOrExpContext varOrExp, IEnumerable<LuaParser.NameAndArgsContext> nameAndArgs)
 			: base(context, lcontext)
 			: base(context, lcontext)
 		{
 		{
 			m_StartingExpression = NodeFactory.CreateExpression(varOrExp, lcontext);
 			m_StartingExpression = NodeFactory.CreateExpression(varOrExp, lcontext);
-			m_CallChain = nameAndArgs.Select(naa => new FunctionCall(naa, lcontext)).ToList();
+			m_CallChain = nameAndArgs.Select(naa => new ANTLR_FunctionCall(naa, lcontext)).ToList();
 		}
 		}
 
 
-		public FunctionCallChainExpression(IParseTree context, ScriptLoadingContext lcontext,
+		public ANTLR_FunctionCallChainExpression(IParseTree context, ScriptLoadingContext lcontext,
 			Expression startingExpression, IEnumerable<LuaParser.NameAndArgsContext> nameAndArgs)
 			Expression startingExpression, IEnumerable<LuaParser.NameAndArgsContext> nameAndArgs)
 			: base(context, lcontext)
 			: base(context, lcontext)
 		{
 		{
 			m_StartingExpression = startingExpression;
 			m_StartingExpression = startingExpression;
-			m_CallChain = nameAndArgs.Select(naa => new FunctionCall(naa, lcontext)).ToList();
+			m_CallChain = nameAndArgs.Select(naa => new ANTLR_FunctionCall(naa, lcontext)).ToList();
 		}
 		}
 
 
 
 
-		public FunctionCallChainExpression(LuaParser.Stat_functioncallContext context, ScriptLoadingContext lcontext)
+		public ANTLR_FunctionCallChainExpression(LuaParser.Stat_functioncallContext context, ScriptLoadingContext lcontext)
 			: this(context, lcontext, context.varOrExp(), context.nameAndArgs())
 			: this(context, lcontext, context.varOrExp(), context.nameAndArgs())
 		{ }
 		{ }
 
 
-		public FunctionCallChainExpression(LuaParser.PrefixexpContext context, ScriptLoadingContext lcontext)
+		public ANTLR_FunctionCallChainExpression(LuaParser.PrefixexpContext context, ScriptLoadingContext lcontext)
 			: this(context, lcontext, context.varOrExp(), context.nameAndArgs())
 			: this(context, lcontext, context.varOrExp(), context.nameAndArgs())
 		{ }
 		{ }
 
 
@@ -44,7 +44,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		{
 		{
 			m_StartingExpression.Compile(bc);
 			m_StartingExpression.Compile(bc);
 
 
-			foreach (FunctionCall fn in m_CallChain)
+			foreach (ANTLR_FunctionCall fn in m_CallChain)
 			{
 			{
 				fn.Compile(bc);
 				fn.Compile(bc);
 			}
 			}

+ 4 - 4
src/MoonSharp.Interpreter/Tree/Statements/FunctionCallStatement.cs → src/MoonSharp.Interpreter/Tree/ANTLR_Deprecated/ANTLR_FunctionCallStatement.cs

@@ -11,15 +11,15 @@ using MoonSharp.Interpreter.Tree.Expressions;
 
 
 namespace MoonSharp.Interpreter.Tree.Statements
 namespace MoonSharp.Interpreter.Tree.Statements
 {
 {
-	class FunctionCallStatement : Statement
+	class ANTLR_FunctionCallStatement : Statement
 	{
 	{
-		FunctionCallChainExpression m_FunctionCallChain;
+		ANTLR_FunctionCallChainExpression m_FunctionCallChain;
 		SourceRef m_SourceRef;
 		SourceRef m_SourceRef;
 
 
-		public FunctionCallStatement(LuaParser.Stat_functioncallContext context, ScriptLoadingContext lcontext)
+		public ANTLR_FunctionCallStatement(LuaParser.Stat_functioncallContext context, ScriptLoadingContext lcontext)
 			: base(context, lcontext)
 			: base(context, lcontext)
 		{
 		{
-			m_FunctionCallChain = new FunctionCallChainExpression(context, lcontext);
+			m_FunctionCallChain = new ANTLR_FunctionCallChainExpression(context, lcontext);
 			m_SourceRef = BuildSourceRef(context.Start, context.Stop);
 			m_SourceRef = BuildSourceRef(context.Start, context.Stop);
 		}
 		}
 
 

+ 0 - 29
src/MoonSharp.Interpreter/Tree/Expression.cs

@@ -1,29 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Antlr4.Runtime.Tree;
-using MoonSharp.Interpreter.Execution;
-using MoonSharp.Interpreter.Grammar;
-
-namespace MoonSharp.Interpreter.Tree
-{
-	abstract class Expression : NodeBase
-	{
-		protected Expression(IParseTree node, ScriptLoadingContext lcontext)
-			: base(node, lcontext)
-		{ }
-
-		public Expression(ScriptLoadingContext lcontext)
-			: base(null, lcontext)
-		{ }
-
-
-		public abstract DynValue Eval(ScriptExecutionContext context);
-
-		public virtual SymbolRef FindDynamic(ScriptExecutionContext context)
-		{
-			return null;
-		}
-	}
-}

+ 78 - 75
src/MoonSharp.Interpreter/Tree/Expressions/BinaryOperatorExpression.cs

@@ -34,6 +34,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			Mul = 0x1000,
 			Mul = 0x1000,
 			Div = 0x2000,
 			Div = 0x2000,
 			Mod = 0x4000,
 			Mod = 0x4000,
+			Power = 0x8000,
 		}
 		}
 
 
 
 
@@ -49,8 +50,10 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		{
 		{
 			public Node Nodes;
 			public Node Nodes;
 			public Node Last;
 			public Node Last;
+			public Operator OperatorMask;
 		}
 		}
 
 
+		const Operator POWER = Operator.Power;
 		const Operator MUL_DIV_MOD = Operator.Mul | Operator.Div | Operator.Mod;
 		const Operator MUL_DIV_MOD = Operator.Mul | Operator.Div | Operator.Mod;
 		const Operator ADD_SUB = Operator.Add | Operator.Sub;
 		const Operator ADD_SUB = Operator.Add | Operator.Sub;
 		const Operator STRCAT = Operator.StrConcat;
 		const Operator STRCAT = Operator.StrConcat;
@@ -58,80 +61,80 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		const Operator LOGIC_AND = Operator.And;
 		const Operator LOGIC_AND = Operator.And;
 		const Operator LOGIC_OR = Operator.Or;
 		const Operator LOGIC_OR = Operator.Or;
 
 
-		private static Operator CreateLinkedList(LinkedList list, IParseTree root, ScriptLoadingContext lcontext)
+
+		public static object BeginOperatorChain()
 		{
 		{
-			Operator opfound = 0;
+			return new LinkedList();
+		}
 
 
-			foreach (IParseTree tt in root.EnumChilds())
-			{
-				Node n = null;
+		public static void AddExpressionToChain(object chain, Expression exp)
+		{
+			LinkedList list = (LinkedList)chain;
+			Node node = new Node() { Expr = exp };
+			AddNode(list, node);
+		}
 
 
-				if (tt is LuaParser.OperatorbinaryContext)
-				{
-					Operator op = ParseBinaryOperator(tt);
-					opfound |= op;
-					n = new Node() { Op = op };
-				}
-				else
-				{
-					if (tt is LuaParser.Exp_binaryContext)
-					{
-						Operator op = CreateLinkedList(list, tt, lcontext);
-						opfound |= op;
-					}
-					else
-					{
-						n = new Node() { Expr = NodeFactory.CreateExpression(tt, lcontext) };
-					}
-				}
 
 
-				if (n != null)
-				{
-					if (list.Nodes == null)
-					{
-						list.Nodes = list.Last = n;
-					}
-					else
-					{
-						list.Last.Next = n;
-						n.Prev = list.Last;
-						list.Last = n;
-					}
-				}
-			}
+		public static void AddOperatorToChain(object chain, Token op)
+		{
+			LinkedList list = (LinkedList)chain;
+			Node node = new Node() { Op = ParseBinaryOperator(op) };
+			AddNode(list, node);
+		}
 
 
-			return opfound;
+		public static Expression CommitOperatorChain(object chain, ScriptLoadingContext lcontext)
+		{
+			return CreateSubTree((LinkedList)chain, lcontext);
+		}
+
+
+
+		private static void AddNode(LinkedList list, Node node)
+		{
+			list.OperatorMask |= node.Op;
+
+			if (list.Nodes == null)
+			{
+				list.Nodes = list.Last = node;
+			}
+			else
+			{
+				list.Last.Next = node;
+				node.Prev = list.Last;
+				list.Last = node;
+			}
 		}
 		}
 
 
 
 
 		/// <summary>
 		/// <summary>
 		/// Creates a sub tree of binary expressions
 		/// Creates a sub tree of binary expressions
 		/// </summary>
 		/// </summary>
-		public static Expression CreateSubTree(IParseTree tree, ScriptLoadingContext lcontext)
+		private static Expression CreateSubTree(LinkedList list, ScriptLoadingContext lcontext)
 		{
 		{
-			LinkedList list = new LinkedList();
-
-			Operator opfound = CreateLinkedList(list, tree, lcontext);
+			Operator opfound = list.OperatorMask;
 
 
 			Node nodes = list.Nodes;
 			Node nodes = list.Nodes;
 
 
+			if ((opfound & POWER) != 0)
+				nodes = PrioritizeRightAssociative(nodes, lcontext, POWER);
+
 			if ((opfound & MUL_DIV_MOD) != 0)
 			if ((opfound & MUL_DIV_MOD) != 0)
-				nodes = PrioritizeLeftAssociative(tree, nodes, lcontext, MUL_DIV_MOD);
+				nodes = PrioritizeLeftAssociative(nodes, lcontext, MUL_DIV_MOD);
 
 
 			if ((opfound & ADD_SUB) != 0)
 			if ((opfound & ADD_SUB) != 0)
-				nodes = PrioritizeLeftAssociative(tree, nodes, lcontext, ADD_SUB);
+				nodes = PrioritizeLeftAssociative(nodes, lcontext, ADD_SUB);
 
 
 			if ((opfound & STRCAT) != 0)
 			if ((opfound & STRCAT) != 0)
-				nodes = PrioritizeRightAssociative(tree, nodes, lcontext, STRCAT);
+				nodes = PrioritizeRightAssociative(nodes, lcontext, STRCAT);
 
 
 			if ((opfound & COMPARES) != 0)
 			if ((opfound & COMPARES) != 0)
-				nodes = PrioritizeLeftAssociative(tree, nodes, lcontext, COMPARES);
+				nodes = PrioritizeLeftAssociative(nodes, lcontext, COMPARES);
 
 
 			if ((opfound & LOGIC_AND) != 0)
 			if ((opfound & LOGIC_AND) != 0)
-				nodes = PrioritizeLeftAssociative(tree, nodes, lcontext, LOGIC_AND);
+				nodes = PrioritizeLeftAssociative(nodes, lcontext, LOGIC_AND);
 
 
 			if ((opfound & LOGIC_OR) != 0)
 			if ((opfound & LOGIC_OR) != 0)
-				nodes = PrioritizeLeftAssociative(tree, nodes, lcontext, LOGIC_OR);
+				nodes = PrioritizeLeftAssociative(nodes, lcontext, LOGIC_OR);
 
 
 
 
 			if (nodes.Next != null || nodes.Prev != null)
 			if (nodes.Next != null || nodes.Prev != null)
@@ -142,7 +145,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			return nodes.Expr;
 			return nodes.Expr;
 		}
 		}
 
 
-		private static Node PrioritizeLeftAssociative(IParseTree tree, Node nodes, ScriptLoadingContext lcontext, Operator operatorsToFind)
+		private static Node PrioritizeLeftAssociative(Node nodes, ScriptLoadingContext lcontext, Operator operatorsToFind)
 		{
 		{
 			for (Node N = nodes; N != null; N = N.Next)
 			for (Node N = nodes; N != null; N = N.Next)
 			{
 			{
@@ -151,7 +154,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 				if ((o & operatorsToFind) != 0)
 				if ((o & operatorsToFind) != 0)
 				{
 				{
 					N.Op = Operator.NotAnOperator;
 					N.Op = Operator.NotAnOperator;
-					N.Expr = new BinaryOperatorExpression(tree, N.Prev.Expr, N.Next.Expr, o, lcontext);
+					N.Expr = new BinaryOperatorExpression(N.Prev.Expr, N.Next.Expr, o, lcontext);
 					N.Prev = N.Prev.Prev;
 					N.Prev = N.Prev.Prev;
 					N.Next = N.Next.Next;
 					N.Next = N.Next.Next;
 
 
@@ -168,7 +171,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			return nodes;
 			return nodes;
 		}
 		}
 
 
-		private static Node PrioritizeRightAssociative(IParseTree tree, Node nodes, ScriptLoadingContext lcontext, Operator operatorsToFind)
+		private static Node PrioritizeRightAssociative(Node nodes, ScriptLoadingContext lcontext, Operator operatorsToFind)
 		{
 		{
 			Node last;
 			Node last;
 			for (last = nodes; last.Next != null; last = last.Next) ;
 			for (last = nodes; last.Next != null; last = last.Next) ;
@@ -180,7 +183,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 				if ((o & operatorsToFind) != 0)
 				if ((o & operatorsToFind) != 0)
 				{
 				{
 					N.Op = Operator.NotAnOperator;
 					N.Op = Operator.NotAnOperator;
-					N.Expr = new BinaryOperatorExpression(tree, N.Prev.Expr, N.Next.Expr, o, lcontext);
+					N.Expr = new BinaryOperatorExpression(N.Prev.Expr, N.Next.Expr, o, lcontext);
 					N.Prev = N.Prev.Prev;
 					N.Prev = N.Prev.Prev;
 					N.Next = N.Next.Next;
 					N.Next = N.Next.Next;
 
 
@@ -198,44 +201,42 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		}
 		}
 
 
 
 
-
-
-		private static Operator ParseBinaryOperator(IParseTree parseTree)
+		private static Operator ParseBinaryOperator(Token token)
 		{
 		{
-			string txt = parseTree.GetText();
-
-			switch (txt)
+			switch (token.Type)
 			{
 			{
-				case "or":
+				case TokenType.Or:
 					return Operator.Or;
 					return Operator.Or;
-				case "and":
+				case TokenType.And:
 					return Operator.And;
 					return Operator.And;
-				case "<":
+				case TokenType.Op_LessThan:
 					return Operator.Less;
 					return Operator.Less;
-				case ">":
+				case TokenType.Op_GreaterThan:
 					return Operator.Greater;
 					return Operator.Greater;
-				case "<=":
+				case TokenType.Op_LessThanEqual:
 					return Operator.LessOrEqual;
 					return Operator.LessOrEqual;
-				case ">=":
+				case TokenType.Op_GreaterThanEqual:
 					return Operator.GreaterOrEqual;
 					return Operator.GreaterOrEqual;
-				case "~=":
+				case TokenType.Op_NotEqual:
 					return Operator.NotEqual;
 					return Operator.NotEqual;
-				case "==":
+				case TokenType.Op_Equal:
 					return Operator.Equal;
 					return Operator.Equal;
-				case "..":
+				case TokenType.Op_Concat:
 					return Operator.StrConcat;
 					return Operator.StrConcat;
-				case "+":
+				case TokenType.Op_Add:
 					return Operator.Add;
 					return Operator.Add;
-				case "-":
+				case TokenType.Op_MinusOrSub:
 					return Operator.Sub;
 					return Operator.Sub;
-				case "*":
+				case TokenType.Op_Mul:
 					return Operator.Mul;
 					return Operator.Mul;
-				case "/":
+				case TokenType.Op_Div:
 					return Operator.Div;
 					return Operator.Div;
-				case "%":
+				case TokenType.Op_Mod:
 					return Operator.Mod;
 					return Operator.Mod;
+				case TokenType.Op_Pwr:
+					return Operator.Power;
 				default:
 				default:
-					throw new InternalErrorException("Unexpected binary operator '{0}'", txt);
+					throw new InternalErrorException("Unexpected binary operator '{0}'", token.Text);
 			}
 			}
 		}
 		}
 
 
@@ -247,8 +248,8 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 
 
 
 
 
 
-		private BinaryOperatorExpression(IParseTree tree, Expression exp1, Expression exp2, Operator op, ScriptLoadingContext lcontext)
-			: base (tree, lcontext)
+		private BinaryOperatorExpression(Expression exp1, Expression exp2, Operator op, ScriptLoadingContext lcontext)
+			: base (lcontext)
 		{
 		{
 			m_Exp1 = exp1;
 			m_Exp1 = exp1;
 			m_Exp2 = exp2;
 			m_Exp2 = exp2;
@@ -287,6 +288,8 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 					return OpCode.Div;
 					return OpCode.Div;
 				case Operator.Mod:
 				case Operator.Mod:
 					return OpCode.Mod;
 					return OpCode.Mod;
+				case Operator.Power:
+					return OpCode.Power;
 				default:
 				default:
 					throw new InternalErrorException("Unsupported operator {0}", op);
 					throw new InternalErrorException("Unsupported operator {0}", op);
 			}
 			}

+ 12 - 6
src/MoonSharp.Interpreter/Tree/Expressions/ExprListExpression.cs

@@ -9,18 +9,24 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 {
 {
 	class ExprListExpression : Expression 
 	class ExprListExpression : Expression 
 	{
 	{
-		Expression[] expressions;
+		List<Expression> expressions;
+
+		public ExprListExpression(List<Expression> exps, ScriptLoadingContext lcontext)
+			: base(lcontext)
+		{
+			expressions = exps;
+		}
 
 
 		public ExprListExpression(LuaParser.ExplistContext tree, ScriptLoadingContext lcontext)
 		public ExprListExpression(LuaParser.ExplistContext tree, ScriptLoadingContext lcontext)
 			: base(tree, lcontext)
 			: base(tree, lcontext)
 		{
 		{
-			expressions = NodeFactory.CreateExpessionArray(tree.children, lcontext);
+			expressions = NodeFactory.CreateExpessionArray(tree.children, lcontext).ToList();
 		}
 		}
 
 
 
 
 		public Expression[] GetExpressions()
 		public Expression[] GetExpressions()
 		{
 		{
-			return expressions;
+			return expressions.ToArray();
 		}
 		}
 
 
 		public override void Compile(Execution.VM.ByteCode bc)
 		public override void Compile(Execution.VM.ByteCode bc)
@@ -28,13 +34,13 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			foreach (var exp in expressions)
 			foreach (var exp in expressions)
 				exp.Compile(bc);
 				exp.Compile(bc);
 
 
-			if (expressions.Length > 1)
-				bc.Emit_MkTuple(expressions.Length);
+			if (expressions.Count > 1)
+				bc.Emit_MkTuple(expressions.Count);
 		}
 		}
 
 
 		public override DynValue Eval(ScriptExecutionContext context)
 		public override DynValue Eval(ScriptExecutionContext context)
 		{
 		{
-			if (expressions.Length > 1)
+			if (expressions.Count >= 1)
 				return expressions[0].Eval(context);
 				return expressions[0].Eval(context);
 
 
 			return DynValue.Void;
 			return DynValue.Void;

+ 87 - 0
src/MoonSharp.Interpreter/Tree/Expressions/FunctionCallExpression.cs

@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MoonSharp.Interpreter.Execution;
+
+namespace MoonSharp.Interpreter.Tree.Expressions
+{
+	class FunctionCallExpression : Expression
+	{
+		List<Expression> m_Arguments;
+		Expression m_Function;
+		string m_Name;
+		string m_DebugErr;
+
+
+		public FunctionCallExpression(ScriptLoadingContext lcontext, Expression function, Token thisCallName)
+			: base(lcontext)
+		{
+			m_Name = thisCallName != null ? thisCallName.Text : null;
+			m_DebugErr = function.GetFriendlyDebugName();
+			m_Function = function;
+
+			switch (lcontext.Lexer.Current().Type)
+			{
+				case TokenType.Brk_Open_Round:
+					lcontext.Lexer.Next();
+					m_Arguments = ExprList(lcontext);
+					CheckMatch(lcontext, "(", 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());
+						lcontext.Lexer.Next();
+						m_Arguments.Add(le);
+					}
+					break;
+				case TokenType.Brk_Open_Curly:
+					{
+						m_Arguments = new List<Expression>();
+						Expression le = new TableConstructor(lcontext);
+						CheckMatch(lcontext, "{", TokenType.Brk_Close_Curly);
+						m_Arguments.Add(le);
+					}
+					break;
+				default:
+					throw new SyntaxErrorException("function arguments expected");
+			}
+		}
+
+		public override void Compile(Execution.VM.ByteCode bc)
+		{
+			m_Function.Compile(bc);
+
+			int argslen = m_Arguments.Count;
+
+			if (!string.IsNullOrEmpty(m_Name))
+			{
+				bc.Emit_Copy(0);
+				bc.Emit_Literal(DynValue.NewString(m_Name));
+				bc.Emit_Index();
+				bc.Emit_Swap(0, 1);
+				++argslen;
+			}
+
+			for (int i = 0; i < m_Arguments.Count; i++)
+				m_Arguments[i].Compile(bc);
+
+			if (!string.IsNullOrEmpty(m_Name))
+			{
+				bc.Emit_ThisCall(argslen, m_DebugErr);
+			}
+			else
+			{
+				bc.Emit_Call(argslen, m_DebugErr);
+			}
+		}
+
+		public override DynValue Eval(ScriptExecutionContext context)
+		{
+			throw new DynamicExpressionException("Dynamic Expressions cannot call functions.");
+		}
+
+	}
+}

+ 9 - 0
src/MoonSharp.Interpreter/Tree/Expressions/IndexExpression.cs

@@ -14,6 +14,15 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		Expression m_BaseExp;
 		Expression m_BaseExp;
 		Expression m_IndexExp;
 		Expression m_IndexExp;
 
 
+
+		public IndexExpression(Expression baseExp, Expression indexExp, ScriptLoadingContext lcontext)
+			: base(lcontext)
+		{
+			m_BaseExp = baseExp;
+			m_IndexExp = indexExp;
+		}
+
+
 		public IndexExpression(IParseTree node, ScriptLoadingContext lcontext, Expression baseExp, Expression indexExp)
 		public IndexExpression(IParseTree node, ScriptLoadingContext lcontext, Expression baseExp, Expression indexExp)
 			:base(node, lcontext)
 			:base(node, lcontext)
 		{
 		{

+ 63 - 6
src/MoonSharp.Interpreter/Tree/Expressions/LiteralExpression.cs

@@ -56,16 +56,68 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			ITerminalNode normStr = context.NORMALSTRING();
 			ITerminalNode normStr = context.NORMALSTRING();
 
 
 			if (charStr != null)
 			if (charStr != null)
-				m_Value = DynValue.NewString(NormalizeNormStr(charStr.GetText())).AsReadOnly();
+				m_Value = DynValue.NewString(NormalizeNormStr(charStr.GetText(), true)).AsReadOnly();
 			else if (longStr != null)
 			else if (longStr != null)
 				m_Value = DynValue.NewString(NormalizeLongStr(longStr.GetText())).AsReadOnly();
 				m_Value = DynValue.NewString(NormalizeLongStr(longStr.GetText())).AsReadOnly();
 			else if (normStr != null)
 			else if (normStr != null)
-				m_Value = DynValue.NewString(NormalizeNormStr(normStr.GetText())).AsReadOnly();
+				m_Value = DynValue.NewString(NormalizeNormStr(normStr.GetText(), true)).AsReadOnly();
 		}
 		}
 
 
-		private string NormalizeNormStr(string str)
+		public LiteralExpression(ScriptLoadingContext lcontext, DynValue value)
+			: base(lcontext)
 		{
 		{
-			str = str.Substring(1, str.Length - 2); // removes "/'
+			m_Value = value;
+		}
+
+
+		public LiteralExpression(ScriptLoadingContext lcontext, Token t)
+			: base(lcontext)
+		{
+			if (t.Type == TokenType.Number)
+			{
+				TryParse(t.Text, s => double.Parse(s, CultureInfo.InvariantCulture));
+			}
+			else if (t.Type == TokenType.Number_Hex)
+			{
+				TryParse(t.Text, s => (double)ulong.Parse(RemoveHexHeader(s), NumberStyles.HexNumber, CultureInfo.InvariantCulture));
+			}
+			else if (t.Type == TokenType.Number_HexFloat)
+			{
+				TryParse(t.Text, s => ParseHexFloat(s));
+			}
+			else if (t.Type == TokenType.String)
+			{
+				m_Value = DynValue.NewString(NormalizeNormStr(t.Text, false)).AsReadOnly();
+			}
+			else if (t.Type == TokenType.String_Long)
+			{
+				m_Value = DynValue.NewString(NormalizeLongStr(t.Text)).AsReadOnly();
+			}
+			else if (t.Type == TokenType.True)
+			{
+				m_Value = DynValue.True;
+			}
+			else if (t.Type == TokenType.False)
+			{
+				m_Value = DynValue.False;
+			}
+			else if (t.Type == TokenType.Nil)
+			{
+				m_Value = DynValue.Nil;
+			}
+			else
+			{
+				throw new InternalErrorException("Type mismatch");
+			}
+
+			if (m_Value == null)
+				throw new SyntaxErrorException("unknown number format near '{0}'", t.Text);
+		}
+
+		private string NormalizeNormStr(string str, bool cutPrefix)
+		{
+			if (cutPrefix) // ANTLR ONLY -- TO REMOVE
+				str = str.Substring(1, str.Length - 2); // removes "/'
 
 
 			if (!str.Contains('\\'))
 			if (!str.Contains('\\'))
 				return str;
 				return str;
@@ -244,6 +296,12 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			return str;
 			return str;
 		}
 		}
 
 
+		private void TryParse(string txt, Func<string, double> parser)
+		{
+			double val = parser(txt);
+			m_Value = DynValue.NewNumber(val).AsReadOnly();
+		}
+
 
 
 		private void TryParse(ITerminalNode terminalNode, Func<string, double> parser)
 		private void TryParse(ITerminalNode terminalNode, Func<string, double> parser)
 		{
 		{
@@ -251,8 +309,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 				return;
 				return;
 
 
 			string txt = terminalNode.GetText();
 			string txt = terminalNode.GetText();
-			double val = parser(txt);
-			m_Value = DynValue.NewNumber(val).AsReadOnly();
+			TryParse(txt, parser);
 		}
 		}
 
 
 		public override void Compile(Execution.VM.ByteCode bc)
 		public override void Compile(Execution.VM.ByteCode bc)

+ 7 - 0
src/MoonSharp.Interpreter/Tree/Expressions/PowerOperatorExpression.cs

@@ -13,6 +13,13 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 	{
 	{
 		Expression m_Exp1, m_Exp2;
 		Expression m_Exp1, m_Exp2;
 
 
+		public PowerOperatorExpression(Expression e1, Expression e2, ScriptLoadingContext lcontext)
+			: base(lcontext)
+		{
+			m_Exp1 = e1;
+			m_Exp2 = e2;
+		}
+
 		public PowerOperatorExpression(IParseTree tree, ScriptLoadingContext lcontext)
 		public PowerOperatorExpression(IParseTree tree, ScriptLoadingContext lcontext)
 			: base(tree, lcontext)
 			: base(tree, lcontext)
 		{
 		{

+ 23 - 0
src/MoonSharp.Interpreter/Tree/Expressions/SymbolRefExpression.cs

@@ -13,6 +13,29 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		SymbolRef m_Ref;
 		SymbolRef m_Ref;
 		string m_VarName;
 		string m_VarName;
 
 
+		public SymbolRefExpression(Token T, ScriptLoadingContext lcontext)
+			: base(lcontext)
+		{
+			m_VarName = T.Text;
+
+			if (T.Type == TokenType.VarArgs)
+			{
+				m_Ref = lcontext.Scope.TryDefineLocal(WellKnownSymbols.VARARGS);
+
+				if (!lcontext.Scope.CurrentFunctionHasVarArgs())
+					throw new SyntaxErrorException("error:0: cannot use '...' outside a vararg function");
+
+				if (lcontext.IsDynamicExpression)
+					throw new DynamicExpressionException("Cannot use '...' in a dynamic expression.");
+			}
+			else
+			{
+				if (!lcontext.IsDynamicExpression)
+					m_Ref = lcontext.Scope.Find(m_VarName);
+			}
+		}
+
+
 		public SymbolRefExpression(IParseTree context, ScriptLoadingContext lcontext, SymbolRef refr)
 		public SymbolRefExpression(IParseTree context, ScriptLoadingContext lcontext, SymbolRef refr)
 			: base(context, lcontext)
 			: base(context, lcontext)
 		{
 		{

+ 8 - 0
src/MoonSharp.Interpreter/Tree/Expressions/TableConstructor.cs

@@ -12,6 +12,14 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		List<Expression> m_PositionalValues = new List<Expression>();
 		List<Expression> m_PositionalValues = new List<Expression>();
 		List<KeyValuePair<Expression, Expression>> m_CtorArgs = new List<KeyValuePair<Expression, Expression>>();
 		List<KeyValuePair<Expression, Expression>> m_CtorArgs = new List<KeyValuePair<Expression, Expression>>();
 
 
+		public TableConstructor(ScriptLoadingContext lcontext)
+			: base(lcontext)
+		{
+			// here lexer is at the '{'
+			throw new NotImplementedException("TableConstructor");
+		}
+
+
 		public TableConstructor(LuaParser.TableconstructorContext context, ScriptLoadingContext lcontext)
 		public TableConstructor(LuaParser.TableconstructorContext context, ScriptLoadingContext lcontext)
 			: base(context, lcontext)
 			: base(context, lcontext)
 		{
 		{

+ 9 - 0
src/MoonSharp.Interpreter/Tree/Expressions/UnaryOperatorExpression.cs

@@ -14,6 +14,15 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		Expression m_Exp;
 		Expression m_Exp;
 		string m_OpText;
 		string m_OpText;
 
 
+		public UnaryOperatorExpression(ScriptLoadingContext lcontext, Expression subExpression, Token unaryOpToken)
+			: base(lcontext)
+		{
+			m_OpText = unaryOpToken.Text;
+			m_Exp = subExpression;
+		}
+
+
+
 		public UnaryOperatorExpression(IParseTree tree, ScriptLoadingContext lcontext)
 		public UnaryOperatorExpression(IParseTree tree, ScriptLoadingContext lcontext)
 			: base(tree, lcontext)
 			: base(tree, lcontext)
 		{
 		{

+ 83 - 45
src/MoonSharp.Interpreter/Tree/Lexer/Lexer.cs

@@ -16,18 +16,25 @@ namespace MoonSharp.Interpreter.Tree
 
 
 		public Lexer(string scriptContent)
 		public Lexer(string scriptContent)
 		{
 		{
-			m_Code = scriptContent; // have a sentinel
+			m_Code = scriptContent; 
 		}
 		}
 
 
 
 
-		public Token PeekToken()
+		public Token Current()
 		{
 		{
 			if (m_Current == null)
 			if (m_Current == null)
-				m_Current = ReadToken();
+				m_Current = LogAndReadToken();
 
 
 			return m_Current;
 			return m_Current;
 		}
 		}
 
 
+		private Token LogAndReadToken()
+		{
+			Token T = ReadToken();
+			System.Diagnostics.Debug.WriteLine("LEXER : " + T.ToString());
+			return T;
+		}
+
 		public Token Next()
 		public Token Next()
 		{
 		{
 			if (m_Current != null)
 			if (m_Current != null)
@@ -37,7 +44,7 @@ namespace MoonSharp.Interpreter.Tree
 				return t;
 				return t;
 			}
 			}
 			else
 			else
-				return ReadToken();
+				return LogAndReadToken();
 		}
 		}
 
 
 		private void CursorNext()
 		private void CursorNext()
@@ -60,17 +67,16 @@ namespace MoonSharp.Interpreter.Tree
 
 
 		private char CursorChar()
 		private char CursorChar()
 		{
 		{
-			return m_Code[m_Cursor];
+			if (m_Cursor < m_Code.Length)
+				return m_Code[m_Cursor];
+			else
+				return '\0'; //  sentinel
 		}
 		}
 
 
 		private char CursorCharNext()
 		private char CursorCharNext()
 		{
 		{
 			m_Cursor += 1;
 			m_Cursor += 1;
-
-			if (m_Cursor < m_Code.Length - 1)
-				return m_Code[m_Cursor];
-			else
-				return '\0'; // fictitious sentinel
+			return CursorChar();	
 		}
 		}
 
 
 		private bool CursorMatches(string pattern)
 		private bool CursorMatches(string pattern)
@@ -94,7 +100,7 @@ namespace MoonSharp.Interpreter.Tree
 
 
 		private bool IsWhiteSpace(char c)
 		private bool IsWhiteSpace(char c)
 		{
 		{
-			return char.IsWhiteSpace(c) || (c == ';');
+			return char.IsWhiteSpace(c);
 		}
 		}
 
 
 		private void SkipWhiteSpace()
 		private void SkipWhiteSpace()
@@ -119,6 +125,9 @@ namespace MoonSharp.Interpreter.Tree
 
 
 			switch (c)
 			switch (c)
 			{
 			{
+				case ';':
+					CursorCharNext();
+					return CreateToken(TokenType.SemiColon, fromLine, fromCol, ";");
 				case '=':
 				case '=':
 					return PotentiallyDoubleCharOperator('=', TokenType.Op_Assignment, TokenType.Op_Equal, fromLine, fromCol);
 					return PotentiallyDoubleCharOperator('=', TokenType.Op_Assignment, TokenType.Op_Equal, fromLine, fromCol);
 				case '<':
 				case '<':
@@ -165,8 +174,8 @@ namespace MoonSharp.Interpreter.Tree
 						char next = CursorCharNext();
 						char next = CursorCharNext();
 						if (next == '=' || next == '[')
 						if (next == '=' || next == '[')
 						{
 						{
-							string str = ReadLongString();
-							return CreateToken(TokenType.LongString, fromLine, fromCol, str);
+							string str = ReadLongString(null);
+							return CreateToken(TokenType.String_Long, fromLine, fromCol, str);
 						}
 						}
 						return CreateToken(TokenType.Brk_Open_Square, fromLine, fromCol, "[");
 						return CreateToken(TokenType.Brk_Open_Square, fromLine, fromCol, "[");
 					}
 					}
@@ -196,8 +205,7 @@ namespace MoonSharp.Interpreter.Tree
 						}
 						}
 						else if (char.IsDigit(c))
 						else if (char.IsDigit(c))
 						{
 						{
-							string number = ReadNumberToken();
-							return CreateToken(TokenType.Number, fromLine, fromCol, number);
+							return ReadNumberToken(fromLine, fromCol);
 						}
 						}
 					}
 					}
 					throw new SyntaxErrorException("Fallback to default ?!", CursorChar());
 					throw new SyntaxErrorException("Fallback to default ?!", CursorChar());
@@ -207,32 +215,39 @@ namespace MoonSharp.Interpreter.Tree
 
 
 		}
 		}
 
 
-		private string ReadLongString()
+		private string ReadLongString(string startpattern)
 		{
 		{
 			// here we are at the first '=' or second '['
 			// here we are at the first '=' or second '['
 			StringBuilder text = new StringBuilder(1024);
 			StringBuilder text = new StringBuilder(1024);
 			string end_pattern = "]";
 			string end_pattern = "]";
-	
-			for (char c = CursorChar(); ; c = CursorCharNext())
+
+			if (startpattern == null)
 			{
 			{
-				if (c == '\0' || !CursorNotEof())
+				for (char c = CursorChar(); ; c = CursorCharNext())
 				{
 				{
-					throw new SyntaxErrorException("Unterminated long string or comment"); 
-				}
-				else if (c == '=')
-				{
-					end_pattern += "=";
-				}
-				else if (c == '[')
-				{
-					end_pattern += "]";
-					break;
-				}
-				else
-				{
-					throw new SyntaxErrorException("Unexpected token in long string prefix: {0}", c);
+					if (c == '\0' || !CursorNotEof())
+					{
+						throw new SyntaxErrorException("Unterminated long string");
+					}
+					else if (c == '=')
+					{
+						end_pattern += "=";
+					}
+					else if (c == '[')
+					{
+						end_pattern += "]";
+						break;
+					}
+					else
+					{
+						throw new SyntaxErrorException("Unexpected token in long string prefix: {0}", c);
+					}
 				}
 				}
 			}
 			}
+			else
+			{
+				end_pattern = startpattern.Replace('[', ']');
+			}
 
 
 
 
 			for (char c = CursorChar(); ; c = CursorCharNext())
 			for (char c = CursorChar(); ; c = CursorCharNext())
@@ -255,7 +270,7 @@ namespace MoonSharp.Interpreter.Tree
 			}
 			}
 		}
 		}
 
 
-		private string ReadNumberToken()
+		private Token ReadNumberToken(int fromLine, int fromCol)
 		{
 		{
 			StringBuilder text = new StringBuilder(32);
 			StringBuilder text = new StringBuilder(32);
 
 
@@ -309,11 +324,18 @@ namespace MoonSharp.Interpreter.Tree
 				}
 				}
 				else
 				else
 				{
 				{
-					return text.ToString();
+					break;
 				}
 				}
 			}
 			}
 
 
-			return text.ToString();
+			TokenType numberType = TokenType.Number;
+
+			if (isHex && (dotAdded || exponentPart))
+				numberType = TokenType.Number_HexFloat;
+			else if (isHex)
+				numberType = TokenType.Number_Hex;
+
+			return CreateToken(numberType, fromLine, fromCol, text.ToString());
 		}
 		}
 
 
 		private bool Char_IsHexDigit(char c)
 		private bool Char_IsHexDigit(char c)
@@ -334,19 +356,28 @@ namespace MoonSharp.Interpreter.Tree
 		{
 		{
 			StringBuilder text = new StringBuilder(32);
 			StringBuilder text = new StringBuilder(32);
 
 
-			char next1 = CursorCharNext();
+			bool extraneousFound = false;
 
 
-			// +++ Long comments
-
-			for (char c = CursorChar(); CursorNotEof(); c = CursorCharNext())
+			for (char c = CursorCharNext(); CursorNotEof(); c = CursorCharNext())
 			{
 			{
-				if (c == '\n')
+				if (c == '[' && !extraneousFound && text.Length > 0)
+				{
+					text.Append('[');
+					CursorCharNext();
+					string comment = ReadLongString(text.ToString());
+					return CreateToken(TokenType.Comment, fromLine, fromCol, comment);
+				}
+				else if (c == '\n')
 				{
 				{
+					extraneousFound = true;
 					CursorCharNext();
 					CursorCharNext();
 					return CreateToken(TokenType.Comment, fromLine, fromCol, text.ToString());
 					return CreateToken(TokenType.Comment, fromLine, fromCol, text.ToString());
 				}
 				}
 				else if (c != '\r')
 				else if (c != '\r')
 				{
 				{
+					if (c != '[' && c != '=')
+						extraneousFound = true;
+
 					text.Append(c);
 					text.Append(c);
 				}
 				}
 			}
 			}
@@ -369,7 +400,7 @@ namespace MoonSharp.Interpreter.Tree
 				else if (c == separator)
 				else if (c == separator)
 				{
 				{
 					CursorCharNext();
 					CursorCharNext();
-					return CreateToken(TokenType.SimpleString, fromLine, fromCol, text.ToString());
+					return CreateToken(TokenType.String, fromLine, fromCol, text.ToString());
 				}
 				}
 				else
 				else
 				{
 				{
@@ -382,10 +413,17 @@ namespace MoonSharp.Interpreter.Tree
 
 
 		private Token PotentiallyDoubleCharOperator(char expectedSecondChar, TokenType singleCharToken, TokenType doubleCharToken, int fromLine, int fromCol)
 		private Token PotentiallyDoubleCharOperator(char expectedSecondChar, TokenType singleCharToken, TokenType doubleCharToken, int fromLine, int fromCol)
 		{
 		{
-			string op = CursorChar().ToString() + CursorCharNext().ToString();
+			string op = CursorChar().ToString();
+			
+			CursorCharNext();
 
 
-			return CreateToken(CursorChar() == expectedSecondChar ? doubleCharToken : singleCharToken,
-				fromLine, fromCol, op);
+			if (CursorChar() == expectedSecondChar)
+			{
+				CursorCharNext();
+				return CreateToken(doubleCharToken, fromLine, fromCol, op + expectedSecondChar);
+			}
+			else
+				return CreateToken(singleCharToken, fromLine, fromCol, op);
 		}
 		}
 
 
 
 

+ 32 - 1
src/MoonSharp.Interpreter/Tree/Lexer/Token.cs

@@ -33,7 +33,7 @@ namespace MoonSharp.Interpreter.Tree
 		public override string ToString()
 		public override string ToString()
 		{
 		{
 			string tokenTypeString = (Type.ToString() + "                                                      ").Substring(0, 16);
 			string tokenTypeString = (Type.ToString() + "                                                      ").Substring(0, 16);
-			return string.Format("{0}  -  {1}", tokenTypeString, this.Text ?? "");
+			return string.Format("{0}  -  '{1}'", tokenTypeString, this.Text ?? "");
 		}
 		}
 
 
 
 
@@ -109,5 +109,36 @@ namespace MoonSharp.Interpreter.Tree
 			}
 			}
 		}
 		}
 
 
+		public bool IsUnaryOperator()
+		{
+			return Type == TokenType.Op_MinusOrSub || Type == TokenType.Not || Type == TokenType.Op_Len;
+		}
+
+		public bool IsBinaryOperator()
+		{
+			switch (Type)
+			{
+				case TokenType.And:
+				case TokenType.Or:
+				case TokenType.Op_Equal:
+				case TokenType.Op_LessThan:
+				case TokenType.Op_LessThanEqual:
+				case TokenType.Op_GreaterThanEqual:
+				case TokenType.Op_GreaterThan:
+				case TokenType.Op_NotEqual:
+				case TokenType.Op_Concat:
+				case TokenType.Op_Pwr:
+				case TokenType.Op_Mod:
+				case TokenType.Op_Div:
+				case TokenType.Op_Mul:
+				case TokenType.Op_MinusOrSub:
+				case TokenType.Op_Add:
+					return true;
+				default:
+					return false;
+			}
+		}
+
+
 	}
 	}
 }
 }

+ 7 - 2
src/MoonSharp.Interpreter/Tree/Lexer/TokenType.cs

@@ -57,10 +57,15 @@ namespace MoonSharp.Interpreter.Tree
 		Op_Mul,
 		Op_Mul,
 		Op_MinusOrSub,
 		Op_MinusOrSub,
 		Op_Add,
 		Op_Add,
-		SimpleString,
 		Comment,
 		Comment,
+
+		String,
+		String_Long,
+
 		Number,
 		Number,
-		LongString,
+		Number_HexFloat,
+		Number_Hex,
+		SemiColon,
 	}
 	}
 
 
 
 

+ 4 - 4
src/MoonSharp.Interpreter/Tree/NodeFactory.cs

@@ -31,7 +31,7 @@ namespace MoonSharp.Interpreter.Tree
 				return new FunctionDefinitionStatement((LuaParser.Stat_localfuncdefContext)tree, lcontext);
 				return new FunctionDefinitionStatement((LuaParser.Stat_localfuncdefContext)tree, lcontext);
 
 
 			if (tree is LuaParser.Stat_functioncallContext)
 			if (tree is LuaParser.Stat_functioncallContext)
-				return new FunctionCallStatement((LuaParser.Stat_functioncallContext)tree, lcontext);
+				return new ANTLR_FunctionCallStatement((LuaParser.Stat_functioncallContext)tree, lcontext);
 
 
 			if (tree is LuaParser.RetstatContext)
 			if (tree is LuaParser.RetstatContext)
 				return new ReturnStatement((LuaParser.RetstatContext)tree, lcontext);
 				return new ReturnStatement((LuaParser.RetstatContext)tree, lcontext);
@@ -141,7 +141,7 @@ namespace MoonSharp.Interpreter.Tree
 			if (tree is LuaParser.Exp_tabctorContext) tree = ((LuaParser.Exp_tabctorContext)tree).tableconstructor();
 			if (tree is LuaParser.Exp_tabctorContext) tree = ((LuaParser.Exp_tabctorContext)tree).tableconstructor();
 			if (tree is LuaParser.Exp_powerContext) return new PowerOperatorExpression(tree, lcontext);
 			if (tree is LuaParser.Exp_powerContext) return new PowerOperatorExpression(tree, lcontext);
 			if (tree is LuaParser.Exp_unaryContext) return new UnaryOperatorExpression(tree, lcontext);
 			if (tree is LuaParser.Exp_unaryContext) return new UnaryOperatorExpression(tree, lcontext);
-			if (tree is LuaParser.Exp_binaryContext) return BinaryOperatorExpression.CreateSubTree(tree, lcontext);
+			if (tree is LuaParser.Exp_binaryContext) return ANTLR_BinaryOperatorExpression.CreateSubTree(tree, lcontext);
 
 
 			if (tree is Antlr4.Runtime.Tree.TerminalNodeImpl)
 			if (tree is Antlr4.Runtime.Tree.TerminalNodeImpl)
 			{
 			{
@@ -157,7 +157,7 @@ namespace MoonSharp.Interpreter.Tree
 			{
 			{
 				var prefix = (LuaParser.PrefixexpContext)tree;
 				var prefix = (LuaParser.PrefixexpContext)tree;
 				if (tree.EnumChilds().OfType<LuaParser.NameAndArgsContext>().Any())
 				if (tree.EnumChilds().OfType<LuaParser.NameAndArgsContext>().Any())
-					return new FunctionCallChainExpression(prefix, lcontext);
+					return new ANTLR_FunctionCallChainExpression(prefix, lcontext);
 				else
 				else
 					return CreateExpression(prefix.varOrExp(), lcontext);
 					return CreateExpression(prefix.varOrExp(), lcontext);
 			}
 			}
@@ -213,7 +213,7 @@ namespace MoonSharp.Interpreter.Tree
 
 
 				if (nameAndArgs != null && nameAndArgs.Length > 0)
 				if (nameAndArgs != null && nameAndArgs.Length > 0)
 				{
 				{
-					varExp = new FunctionCallChainExpression(suffix, lcontext, varExp, nameAndArgs);
+					varExp = new ANTLR_FunctionCallChainExpression(suffix, lcontext, varExp, nameAndArgs);
 				}
 				}
 
 
 				varExp = new IndexExpression(suffix, lcontext, varExp, indexExp);
 				varExp = new IndexExpression(suffix, lcontext, varExp, indexExp);

+ 4 - 2
src/MoonSharp.Interpreter/Tree/Statement.cs

@@ -26,7 +26,7 @@ namespace MoonSharp.Interpreter.Tree
 
 
 		protected static Statement CreateStatement(ScriptLoadingContext lcontext, out bool forceLast)
 		protected static Statement CreateStatement(ScriptLoadingContext lcontext, out bool forceLast)
 		{
 		{
-			Token tkn = lcontext.Lexer.PeekToken();
+			Token tkn = lcontext.Lexer.Current();
 
 
 			forceLast = false;
 			forceLast = false;
 
 
@@ -48,7 +48,7 @@ namespace MoonSharp.Interpreter.Tree
 					throw new NotImplementedException();
 					throw new NotImplementedException();
 				case TokenType.Return:
 				case TokenType.Return:
 					forceLast = true;
 					forceLast = true;
-					throw new NotImplementedException();
+					return new ReturnStatement(lcontext);
 				case TokenType.Break:
 				case TokenType.Break:
 					forceLast = true;
 					forceLast = true;
 					throw new NotImplementedException();
 					throw new NotImplementedException();
@@ -56,6 +56,8 @@ namespace MoonSharp.Interpreter.Tree
 					throw new NotImplementedException();
 					throw new NotImplementedException();
 			}
 			}
 		}
 		}
+
+
 	}
 	}
 
 
 
 

+ 17 - 7
src/MoonSharp.Interpreter/Tree/Statements/ChunkStatement.cs

@@ -21,18 +21,28 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		SymbolRef m_Env;
 		SymbolRef m_Env;
 		SymbolRef m_VarArgs;
 		SymbolRef m_VarArgs;
 
 
-		public ChunkStatement(Lexer lexer, ScriptLoadingContext lcontext, Table globalEnv)
+		public ChunkStatement(ScriptLoadingContext lcontext, Table globalEnv)
 			: base(lcontext)
 			: base(lcontext)
 		{
 		{
-			//lcontext.Scope.PushFunction(this, true);
-			//m_Env = lcontext.Scope.DefineLocal(WellKnownSymbols.ENV);
-			//m_VarArgs = lcontext.Scope.DefineLocal(WellKnownSymbols.VARARGS);
+			lcontext.Scope.PushFunction(this, true);
+			m_Env = lcontext.Scope.DefineLocal(WellKnownSymbols.ENV);
+			m_VarArgs = lcontext.Scope.DefineLocal(WellKnownSymbols.VARARGS);
+
+			m_GlobalEnv = globalEnv;
+
+			m_Block = new CompositeStatement(lcontext);
 
 
-			//m_GlobalEnv = globalEnv;
+			Token T = lcontext.Lexer.Current();
 
 
-			//m_Block = new CompositeStatement(lexer, lcontext);
+			while (T.Type == TokenType.SemiColon)
+				T = lcontext.Lexer.Next();
 
 
-			//m_StackFrame = lcontext.Scope.PopFunction();
+			if (T.Type != TokenType.Eof)
+			{
+				throw new SyntaxErrorException("<eof> expected near '{0}'", T.Text);
+			}
+
+			m_StackFrame = lcontext.Scope.PopFunction();
 		}
 		}
 
 
 
 

+ 1 - 1
src/MoonSharp.Interpreter/Tree/Statements/CompositeStatement.cs

@@ -41,7 +41,7 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		{
 		{
 			while (true)
 			while (true)
 			{
 			{
-				Token t = lcontext.Lexer.PeekToken();
+				Token t = lcontext.Lexer.Current();
 				if (t.IsEndOfBlock()) break;
 				if (t.IsEndOfBlock()) break;
 
 
 				bool forceLast;
 				bool forceLast;

+ 18 - 0
src/MoonSharp.Interpreter/Tree/Statements/ReturnStatement.cs

@@ -14,6 +14,24 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		Expression m_Expression = null;
 		Expression m_Expression = null;
 		SourceRef m_Ref;
 		SourceRef m_Ref;
 
 
+		public ReturnStatement(ScriptLoadingContext lcontext)
+			: base(lcontext)
+		{
+			lcontext.Lexer.Next();
+
+			Token cur = lcontext.Lexer.Current();
+
+			if (cur.IsEndOfBlock() || cur.Type == TokenType.SemiColon)
+			{
+				m_Expression = null;
+			}
+			else
+			{
+				m_Expression = new ExprListExpression(Expression.ExprList(lcontext), lcontext);
+			}
+		}
+
+
 		public ReturnStatement(LuaParser.RetstatContext context, ScriptLoadingContext lcontext)
 		public ReturnStatement(LuaParser.RetstatContext context, ScriptLoadingContext lcontext)
 			: base(context, lcontext)
 			: base(context, lcontext)
 		{
 		{

+ 235 - 0
src/MoonSharp.Interpreter/Tree/__Expression.cs

@@ -0,0 +1,235 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Antlr4.Runtime.Tree;
+using MoonSharp.Interpreter.Execution;
+using MoonSharp.Interpreter.Grammar;
+using MoonSharp.Interpreter.Tree.Expressions;
+
+namespace MoonSharp.Interpreter.Tree
+{
+	abstract class Expression : NodeBase
+	{
+		protected Expression(IParseTree node, ScriptLoadingContext lcontext)
+			: base(node, lcontext)
+		{ }
+
+		public Expression(ScriptLoadingContext lcontext)
+			: base(null, lcontext)
+		{ }
+
+		public virtual string GetFriendlyDebugName()
+		{
+			return null;
+		}
+
+		public abstract DynValue Eval(ScriptExecutionContext context);
+
+		public virtual SymbolRef FindDynamic(ScriptExecutionContext context)
+		{
+			return null;
+		}
+
+
+		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; //+++
+		}
+
+		internal static Expression Expr(ScriptLoadingContext lcontext)
+		{
+			return SubExpr(lcontext, true);
+		}
+
+		internal static Expression SubExpr(ScriptLoadingContext lcontext, bool isPrimary)
+		{
+			Expression e = null;
+
+			Token T = lcontext.Lexer.Current();
+
+			if (T.IsUnaryOperator())
+			{
+				lcontext.Lexer.Next();
+				e = SubExpr(lcontext, false);
+
+				// check for power operator "damnedness"
+				Token unaryOp = T;
+				T = lcontext.Lexer.Current();
+
+				if (isPrimary && T.Type == TokenType.Op_Pwr)
+				{
+					List<Expression> powerChain = new List<Expression>();
+					powerChain.Add(e);
+
+					while (isPrimary && T.Type == TokenType.Op_Pwr)
+					{
+						lcontext.Lexer.Next();
+						powerChain.Add(SubExpr(lcontext, false));
+						T = lcontext.Lexer.Current();
+					}
+
+					e = powerChain[powerChain.Count - 1];
+
+					for (int i = powerChain.Count - 2; i >= 0; i--)
+					{
+						e = new PowerOperatorExpression(powerChain[i], e, lcontext);
+					}
+				}
+
+				e = new UnaryOperatorExpression(lcontext, e, unaryOp);
+			}
+			else
+			{
+				e = SimpleExp(lcontext);
+			}
+
+			T = lcontext.Lexer.Current();
+
+			if (isPrimary && T.IsBinaryOperator())
+			{
+				object chain = BinaryOperatorExpression.BeginOperatorChain();
+
+				BinaryOperatorExpression.AddExpressionToChain(chain, e);
+
+				while (T.IsBinaryOperator())
+				{
+					BinaryOperatorExpression.AddOperatorToChain(chain, T);
+					lcontext.Lexer.Next();
+					Expression right = SubExpr(lcontext, false);
+					BinaryOperatorExpression.AddExpressionToChain(chain, right);
+					T = lcontext.Lexer.Current();
+				}
+
+				e = BinaryOperatorExpression.CommitOperatorChain(chain, lcontext);
+			}
+
+			return e;
+		}
+
+		internal static Expression SimpleExp(ScriptLoadingContext lcontext)
+		{
+			Token t = lcontext.Lexer.Current();
+
+			switch (t.Type)
+			{
+				case TokenType.Number:
+				case TokenType.Number_Hex:
+				case TokenType.Number_HexFloat:
+				case TokenType.String:
+				case TokenType.String_Long:
+				case TokenType.Nil:
+				case TokenType.True:
+				case TokenType.False:
+					lcontext.Lexer.Next();
+					return new LiteralExpression(lcontext, t);
+				case TokenType.VarArgs:
+					lcontext.Lexer.Next();
+					return new SymbolRefExpression(t, lcontext);
+				case TokenType.Brk_Open_Curly:
+					{
+						Expression tc = new TableConstructor(lcontext);
+						CheckMatch(lcontext, "{", TokenType.Brk_Close_Curly);
+						return tc;
+					}
+				case TokenType.Function:
+					throw new NotImplementedException();
+				default:
+					return PrimaryExp(lcontext);
+			}
+
+		}
+
+		private static Expression PrimaryExp(ScriptLoadingContext lcontext)
+		{
+			Expression e = PrefixExp(lcontext);
+
+			while (true)
+			{
+				Token T = lcontext.Lexer.Current();
+				Token thisCallName = null;
+
+				switch (T.Type)
+				{
+					case TokenType.Dot:
+						{
+							Token name = lcontext.Lexer.Next();
+							CheckTokenType(name, TokenType.Name);
+							LiteralExpression le = new LiteralExpression(lcontext, DynValue.NewString(name.Text));
+							lcontext.Lexer.Next();
+							return new IndexExpression(e, le, lcontext);
+						}
+					case TokenType.Brk_Open_Square:
+						{
+							lcontext.Lexer.Next(); // skip bracket
+							Expression index = Expr(lcontext);
+							CheckMatch(lcontext, T.Text, TokenType.Brk_Close_Square);
+							return new IndexExpression(e, index, lcontext);
+						}
+					case TokenType.Colon:
+							thisCallName = lcontext.Lexer.Next();
+							CheckTokenType(thisCallName, TokenType.Name);
+							lcontext.Lexer.Next();
+							goto case TokenType.Brk_Open_Round;
+					case TokenType.Brk_Open_Round:
+					case TokenType.String:
+					case TokenType.String_Long:
+					case TokenType.Brk_Open_Curly:
+							return new FunctionCallExpression(lcontext, e, thisCallName);
+					default: 
+						return e;
+				}
+			}
+		}
+
+		private static void CheckTokenType(Token t, TokenType tokenType)
+		{
+			if (t.Type != tokenType)
+				throw new SyntaxErrorException("Unexpected token '{0}'", t.Text);
+		}
+
+		private static Expression PrefixExp(ScriptLoadingContext lcontext)
+		{
+			Token T = lcontext.Lexer.Current();
+			switch (T.Type)
+			{
+				case TokenType.Brk_Open_Round:
+					lcontext.Lexer.Next();
+					Expression e = Expr(lcontext);
+					CheckMatch(lcontext, T.Text, TokenType.Brk_Close_Round);
+					return e;
+				case TokenType.Name:
+					lcontext.Lexer.Next();
+					return new SymbolRefExpression(T, lcontext);
+				default:
+					throw new SyntaxErrorException("unexpected symbol near '{0}'", T.Text);
+			}
+		}
+
+		protected static void CheckMatch(ScriptLoadingContext lcontext, string tokenDesc, TokenType tokenType)
+		{
+			if (lcontext.Lexer.Current().Type != tokenType)
+				throw new SyntaxErrorException("Mismatched '{0}' near '{1}'", tokenDesc, lcontext.Lexer.Current().Text);
+
+			lcontext.Lexer.Next();
+		}
+
+		private static Expression SingleVar(ScriptLoadingContext lcontext)
+		{
+			throw new NotImplementedException();
+		}
+
+	}
+}