Browse Source

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

Xanathar 10 năm trước cách đây
mục cha
commit
e9bb7f19f9
26 tập tin đã thay đổi với 802 bổ sung201 xóa
  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);
 		}
 
+		[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]
 		public void CSharpStaticFunctionCall()
 		{
@@ -151,6 +170,7 @@ namespace MoonSharp.Interpreter.Tests
 		[Test]
 		public void ParserErrorMessage()
 		{
+			bool caught = false;
 			string script = @"    
 				return 'It's a wet floor warning saying wheat flour instead. \
 				Probably, the cook thought it was funny. \
@@ -162,10 +182,25 @@ namespace MoonSharp.Interpreter.Tests
 			}
 			catch (SyntaxErrorException ex)
 			{
+				caught = true;
 				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]
 		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]
@@ -622,6 +678,17 @@ namespace MoonSharp.Interpreter.Tests
 			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]

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

@@ -20,5 +20,18 @@ namespace MoonSharp.Interpreter.Execution
 		{
 			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\Expressions\AdjustmentExpression.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\FunctionCallExpression.cs" />
     <Compile Include="Tree\Expressions\PowerOperatorExpression.cs" />
     <Compile Include="Tree\Expressions\UnaryOperatorExpression.cs" />
+    <Compile Include="Tree\Fast_Interface\Loader_Fast.cs" />
     <Compile Include="Tree\IVariable.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Tree\Expressions\ExprListExpression.cs" />
     <Compile Include="Tree\Expressions\FunctionDefinitionExpression.cs" />
     <Compile Include="Tree\Expressions\LiteralExpression.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\SymbolRefExpression.cs" />
     <Compile Include="Tree\Antlr_Interface\Loader_Antlr.cs" />
@@ -281,7 +284,7 @@
     <Compile Include="Tree\Statements\BreakStatement.cs" />
     <Compile Include="Tree\Statements\ForEachLoopStatement.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\IfStatement.cs" />
     <Compile Include="Tree\Statement.cs" />
@@ -306,9 +309,7 @@
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Tree\Fast_Interface\" />
-  </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>

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

@@ -15,6 +15,7 @@ using MoonSharp.Interpreter.IO;
 using MoonSharp.Interpreter.Loaders;
 using MoonSharp.Interpreter.Tree;
 using MoonSharp.Interpreter.Tree.Expressions;
+using MoonSharp.Interpreter.Tree.Fast_Interface;
 using MoonSharp.Interpreter.Tree.Statements;
 
 namespace MoonSharp.Interpreter
@@ -171,7 +172,7 @@ namespace MoonSharp.Interpreter
 
 			m_Sources.Add(source);
 
-			int address = Loader_Antlr.LoadChunk(this,
+			int address = Loader_Fast.LoadChunk(this,
 				source,
 				m_ByteCode,
 				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
 {
-	class FunctionCall : NodeBase
+	class ANTLR_FunctionCall : NodeBase
 	{
 		Expression[] m_Arguments;
 		string m_Name;
 		string m_DebugErr;
 
-		public FunctionCall(LuaParser.NameAndArgsContext nameAndArgs, ScriptLoadingContext lcontext)
+		public ANTLR_FunctionCall(LuaParser.NameAndArgsContext nameAndArgs, ScriptLoadingContext lcontext)
 			: base(nameAndArgs, lcontext)
 		{
 			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
 {
-	class FunctionCallChainExpression : Expression
+	class ANTLR_FunctionCallChainExpression : Expression
 	{
 		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)
 			: base(context, 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)
 			: base(context, lcontext)
 		{
 			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())
 		{ }
 
-		public FunctionCallChainExpression(LuaParser.PrefixexpContext context, ScriptLoadingContext lcontext)
+		public ANTLR_FunctionCallChainExpression(LuaParser.PrefixexpContext context, ScriptLoadingContext lcontext)
 			: this(context, lcontext, context.varOrExp(), context.nameAndArgs())
 		{ }
 
@@ -44,7 +44,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		{
 			m_StartingExpression.Compile(bc);
 
-			foreach (FunctionCall fn in m_CallChain)
+			foreach (ANTLR_FunctionCall fn in m_CallChain)
 			{
 				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
 {
-	class FunctionCallStatement : Statement
+	class ANTLR_FunctionCallStatement : Statement
 	{
-		FunctionCallChainExpression m_FunctionCallChain;
+		ANTLR_FunctionCallChainExpression m_FunctionCallChain;
 		SourceRef m_SourceRef;
 
-		public FunctionCallStatement(LuaParser.Stat_functioncallContext context, ScriptLoadingContext lcontext)
+		public ANTLR_FunctionCallStatement(LuaParser.Stat_functioncallContext context, ScriptLoadingContext lcontext)
 			: base(context, lcontext)
 		{
-			m_FunctionCallChain = new FunctionCallChainExpression(context, lcontext);
+			m_FunctionCallChain = new ANTLR_FunctionCallChainExpression(context, lcontext);
 			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,
 			Div = 0x2000,
 			Mod = 0x4000,
+			Power = 0x8000,
 		}
 
 
@@ -49,8 +50,10 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		{
 			public Node Nodes;
 			public Node Last;
+			public Operator OperatorMask;
 		}
 
+		const Operator POWER = Operator.Power;
 		const Operator MUL_DIV_MOD = Operator.Mul | Operator.Div | Operator.Mod;
 		const Operator ADD_SUB = Operator.Add | Operator.Sub;
 		const Operator STRCAT = Operator.StrConcat;
@@ -58,80 +61,80 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		const Operator LOGIC_AND = Operator.And;
 		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>
 		/// Creates a sub tree of binary expressions
 		/// </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;
 
+			if ((opfound & POWER) != 0)
+				nodes = PrioritizeRightAssociative(nodes, lcontext, POWER);
+
 			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)
-				nodes = PrioritizeLeftAssociative(tree, nodes, lcontext, ADD_SUB);
+				nodes = PrioritizeLeftAssociative(nodes, lcontext, ADD_SUB);
 
 			if ((opfound & STRCAT) != 0)
-				nodes = PrioritizeRightAssociative(tree, nodes, lcontext, STRCAT);
+				nodes = PrioritizeRightAssociative(nodes, lcontext, STRCAT);
 
 			if ((opfound & COMPARES) != 0)
-				nodes = PrioritizeLeftAssociative(tree, nodes, lcontext, COMPARES);
+				nodes = PrioritizeLeftAssociative(nodes, lcontext, COMPARES);
 
 			if ((opfound & LOGIC_AND) != 0)
-				nodes = PrioritizeLeftAssociative(tree, nodes, lcontext, LOGIC_AND);
+				nodes = PrioritizeLeftAssociative(nodes, lcontext, LOGIC_AND);
 
 			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)
@@ -142,7 +145,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			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)
 			{
@@ -151,7 +154,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 				if ((o & operatorsToFind) != 0)
 				{
 					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.Next = N.Next.Next;
 
@@ -168,7 +171,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			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;
 			for (last = nodes; last.Next != null; last = last.Next) ;
@@ -180,7 +183,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 				if ((o & operatorsToFind) != 0)
 				{
 					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.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;
-				case "and":
+				case TokenType.And:
 					return Operator.And;
-				case "<":
+				case TokenType.Op_LessThan:
 					return Operator.Less;
-				case ">":
+				case TokenType.Op_GreaterThan:
 					return Operator.Greater;
-				case "<=":
+				case TokenType.Op_LessThanEqual:
 					return Operator.LessOrEqual;
-				case ">=":
+				case TokenType.Op_GreaterThanEqual:
 					return Operator.GreaterOrEqual;
-				case "~=":
+				case TokenType.Op_NotEqual:
 					return Operator.NotEqual;
-				case "==":
+				case TokenType.Op_Equal:
 					return Operator.Equal;
-				case "..":
+				case TokenType.Op_Concat:
 					return Operator.StrConcat;
-				case "+":
+				case TokenType.Op_Add:
 					return Operator.Add;
-				case "-":
+				case TokenType.Op_MinusOrSub:
 					return Operator.Sub;
-				case "*":
+				case TokenType.Op_Mul:
 					return Operator.Mul;
-				case "/":
+				case TokenType.Op_Div:
 					return Operator.Div;
-				case "%":
+				case TokenType.Op_Mod:
 					return Operator.Mod;
+				case TokenType.Op_Pwr:
+					return Operator.Power;
 				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_Exp2 = exp2;
@@ -287,6 +288,8 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 					return OpCode.Div;
 				case Operator.Mod:
 					return OpCode.Mod;
+				case Operator.Power:
+					return OpCode.Power;
 				default:
 					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 
 	{
-		Expression[] expressions;
+		List<Expression> expressions;
+
+		public ExprListExpression(List<Expression> exps, ScriptLoadingContext lcontext)
+			: base(lcontext)
+		{
+			expressions = exps;
+		}
 
 		public ExprListExpression(LuaParser.ExplistContext tree, ScriptLoadingContext lcontext)
 			: base(tree, lcontext)
 		{
-			expressions = NodeFactory.CreateExpessionArray(tree.children, lcontext);
+			expressions = NodeFactory.CreateExpessionArray(tree.children, lcontext).ToList();
 		}
 
 
 		public Expression[] GetExpressions()
 		{
-			return expressions;
+			return expressions.ToArray();
 		}
 
 		public override void Compile(Execution.VM.ByteCode bc)
@@ -28,13 +34,13 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			foreach (var exp in expressions)
 				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)
 		{
-			if (expressions.Length > 1)
+			if (expressions.Count >= 1)
 				return expressions[0].Eval(context);
 
 			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_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)
 			: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();
 
 			if (charStr != null)
-				m_Value = DynValue.NewString(NormalizeNormStr(charStr.GetText())).AsReadOnly();
+				m_Value = DynValue.NewString(NormalizeNormStr(charStr.GetText(), true)).AsReadOnly();
 			else if (longStr != null)
 				m_Value = DynValue.NewString(NormalizeLongStr(longStr.GetText())).AsReadOnly();
 			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('\\'))
 				return str;
@@ -244,6 +296,12 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			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)
 		{
@@ -251,8 +309,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 				return;
 
 			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)

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

@@ -13,6 +13,13 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 	{
 		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)
 			: base(tree, lcontext)
 		{

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

@@ -13,6 +13,29 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		SymbolRef m_Ref;
 		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)
 			: 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<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)
 			: base(context, lcontext)
 		{

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

@@ -14,6 +14,15 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 		Expression m_Exp;
 		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)
 			: base(tree, lcontext)
 		{

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

@@ -16,18 +16,25 @@ namespace MoonSharp.Interpreter.Tree
 
 		public Lexer(string scriptContent)
 		{
-			m_Code = scriptContent; // have a sentinel
+			m_Code = scriptContent; 
 		}
 
 
-		public Token PeekToken()
+		public Token Current()
 		{
 			if (m_Current == null)
-				m_Current = ReadToken();
+				m_Current = LogAndReadToken();
 
 			return m_Current;
 		}
 
+		private Token LogAndReadToken()
+		{
+			Token T = ReadToken();
+			System.Diagnostics.Debug.WriteLine("LEXER : " + T.ToString());
+			return T;
+		}
+
 		public Token Next()
 		{
 			if (m_Current != null)
@@ -37,7 +44,7 @@ namespace MoonSharp.Interpreter.Tree
 				return t;
 			}
 			else
-				return ReadToken();
+				return LogAndReadToken();
 		}
 
 		private void CursorNext()
@@ -60,17 +67,16 @@ namespace MoonSharp.Interpreter.Tree
 
 		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()
 		{
 			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)
@@ -94,7 +100,7 @@ namespace MoonSharp.Interpreter.Tree
 
 		private bool IsWhiteSpace(char c)
 		{
-			return char.IsWhiteSpace(c) || (c == ';');
+			return char.IsWhiteSpace(c);
 		}
 
 		private void SkipWhiteSpace()
@@ -119,6 +125,9 @@ namespace MoonSharp.Interpreter.Tree
 
 			switch (c)
 			{
+				case ';':
+					CursorCharNext();
+					return CreateToken(TokenType.SemiColon, fromLine, fromCol, ";");
 				case '=':
 					return PotentiallyDoubleCharOperator('=', TokenType.Op_Assignment, TokenType.Op_Equal, fromLine, fromCol);
 				case '<':
@@ -165,8 +174,8 @@ namespace MoonSharp.Interpreter.Tree
 						char next = CursorCharNext();
 						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, "[");
 					}
@@ -196,8 +205,7 @@ namespace MoonSharp.Interpreter.Tree
 						}
 						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());
@@ -207,32 +215,39 @@ namespace MoonSharp.Interpreter.Tree
 
 		}
 
-		private string ReadLongString()
+		private string ReadLongString(string startpattern)
 		{
 			// here we are at the first '=' or second '['
 			StringBuilder text = new StringBuilder(1024);
 			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())
@@ -255,7 +270,7 @@ namespace MoonSharp.Interpreter.Tree
 			}
 		}
 
-		private string ReadNumberToken()
+		private Token ReadNumberToken(int fromLine, int fromCol)
 		{
 			StringBuilder text = new StringBuilder(32);
 
@@ -309,11 +324,18 @@ namespace MoonSharp.Interpreter.Tree
 				}
 				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)
@@ -334,19 +356,28 @@ namespace MoonSharp.Interpreter.Tree
 		{
 			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();
 					return CreateToken(TokenType.Comment, fromLine, fromCol, text.ToString());
 				}
 				else if (c != '\r')
 				{
+					if (c != '[' && c != '=')
+						extraneousFound = true;
+
 					text.Append(c);
 				}
 			}
@@ -369,7 +400,7 @@ namespace MoonSharp.Interpreter.Tree
 				else if (c == separator)
 				{
 					CursorCharNext();
-					return CreateToken(TokenType.SimpleString, fromLine, fromCol, text.ToString());
+					return CreateToken(TokenType.String, fromLine, fromCol, text.ToString());
 				}
 				else
 				{
@@ -382,10 +413,17 @@ namespace MoonSharp.Interpreter.Tree
 
 		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()
 		{
 			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_MinusOrSub,
 		Op_Add,
-		SimpleString,
 		Comment,
+
+		String,
+		String_Long,
+
 		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);
 
 			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)
 				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_powerContext) return new PowerOperatorExpression(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)
 			{
@@ -157,7 +157,7 @@ namespace MoonSharp.Interpreter.Tree
 			{
 				var prefix = (LuaParser.PrefixexpContext)tree;
 				if (tree.EnumChilds().OfType<LuaParser.NameAndArgsContext>().Any())
-					return new FunctionCallChainExpression(prefix, lcontext);
+					return new ANTLR_FunctionCallChainExpression(prefix, lcontext);
 				else
 					return CreateExpression(prefix.varOrExp(), lcontext);
 			}
@@ -213,7 +213,7 @@ namespace MoonSharp.Interpreter.Tree
 
 				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);

+ 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)
 		{
-			Token tkn = lcontext.Lexer.PeekToken();
+			Token tkn = lcontext.Lexer.Current();
 
 			forceLast = false;
 
@@ -48,7 +48,7 @@ namespace MoonSharp.Interpreter.Tree
 					throw new NotImplementedException();
 				case TokenType.Return:
 					forceLast = true;
-					throw new NotImplementedException();
+					return new ReturnStatement(lcontext);
 				case TokenType.Break:
 					forceLast = true;
 					throw new NotImplementedException();
@@ -56,6 +56,8 @@ namespace MoonSharp.Interpreter.Tree
 					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_VarArgs;
 
-		public ChunkStatement(Lexer lexer, ScriptLoadingContext lcontext, Table globalEnv)
+		public ChunkStatement(ScriptLoadingContext lcontext, Table globalEnv)
 			: 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)
 			{
-				Token t = lcontext.Lexer.PeekToken();
+				Token t = lcontext.Lexer.Current();
 				if (t.IsEndOfBlock()) break;
 
 				bool forceLast;

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

@@ -14,6 +14,24 @@ namespace MoonSharp.Interpreter.Tree.Statements
 		Expression m_Expression = null;
 		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)
 			: 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();
+		}
+
+	}
+}