Xanathar 10 éve
szülő
commit
a97efa1789

+ 1 - 1
LICENSE

@@ -7,7 +7,7 @@ Copyright (c) 2012 LoDC
 Debugger icons are from the Eclipse project (https://www.eclipse.org/).
 Debugger icons are from the Eclipse project (https://www.eclipse.org/).
 Copyright of The Eclipse Foundation
 Copyright of The Eclipse Foundation
 
 
-The MoonSharp icon is (c) Isaac, 2014
+The MoonSharp icon is (c) Isaac, 2014-2015
 
 
 
 
 Redistribution and use in source and binary forms, with or without
 Redistribution and use in source and binary forms, with or without

+ 1 - 1
src/DevTools/MoonSharp.VmDebugger/Properties/AssemblyInfo.cs

@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyProduct("MoonSharp.Debugger")]
 [assembly: AssemblyProduct("MoonSharp.Debugger")]
-[assembly: AssemblyCopyright("Copyright ©  2014")]
+[assembly: AssemblyCopyright("Copyright ©  2014-2015")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 [assembly: AssemblyCulture("")]
 
 

+ 1 - 1
src/DevTools/PerformanceComparison/Properties/AssemblyInfo.cs

@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyProduct("PerformanceComparison")]
 [assembly: AssemblyProduct("PerformanceComparison")]
-[assembly: AssemblyCopyright("Copyright ©  2014")]
+[assembly: AssemblyCopyright("Copyright ©  2014-2015")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 [assembly: AssemblyCulture("")]
 
 

+ 13 - 8
src/MoonSharp.Interpreter/CoreLib/DebugModule.cs

@@ -4,6 +4,7 @@ using System.Linq;
 using System.Text;
 using System.Text;
 using MoonSharp.Interpreter.Debugging;
 using MoonSharp.Interpreter.Debugging;
 using MoonSharp.Interpreter.Execution;
 using MoonSharp.Interpreter.Execution;
+using MoonSharp.Interpreter.REPL;
 
 
 namespace MoonSharp.Interpreter.CoreLib
 namespace MoonSharp.Interpreter.CoreLib
 {
 {
@@ -17,21 +18,25 @@ namespace MoonSharp.Interpreter.CoreLib
 		public static DynValue debug(ScriptExecutionContext executionContext, CallbackArguments args)
 		public static DynValue debug(ScriptExecutionContext executionContext, CallbackArguments args)
 		{
 		{
 			Script script = executionContext.GetScript();
 			Script script = executionContext.GetScript();
+			
+			ReplInterpreter interpreter = new ReplInterpreter(script)
+				{
+					HandleDynamicExprs = false,
+					HandleClassicExprsSyntax = true
+				};
 
 
 			while (true)
 			while (true)
 			{
 			{
+				string s = script.Options.DebugInput(interpreter.ClassicPrompt + " ");
+
 				try
 				try
 				{
 				{
-					string cmd = script.Options.DebugInput();
-
-					if (cmd == "cont")
-						return DynValue.Void;
+					DynValue result = interpreter.ExecuteRepl(s);
 
 
-					DynValue v = script.LoadString(cmd, null, "stdin");
-					DynValue result = script.Call(v);
-					script.Options.DebugPrint(string.Format("={0}", result));
+					if (result != null && result.Type != DataType.Void)
+						script.Options.DebugPrint(string.Format("{0}", result));
 				}
 				}
-				catch (ScriptRuntimeException ex)
+				catch (InterpreterException ex)
 				{
 				{
 					script.Options.DebugPrint(string.Format("{0}", ex.DecoratedMessage ?? ex.Message));
 					script.Options.DebugPrint(string.Format("{0}", ex.DecoratedMessage ?? ex.Message));
 				}
 				}

+ 6 - 0
src/MoonSharp.Interpreter/Errors/SyntaxErrorException.cs

@@ -16,6 +16,12 @@ namespace MoonSharp.Interpreter
 	{
 	{
 		internal Token Token { get; private set; }
 		internal Token Token { get; private set; }
 
 
+		/// <summary>
+		/// Gets or sets a value indicating whether this exception was caused by premature stream termination (that is, unexpected EOF).
+		/// This can be used in REPL interfaces to tell between unrecoverable errors and those which can be recovered by extra input.
+		/// </summary>
+		public bool IsPrematureStreamTermination { get; set; }
+
 		internal SyntaxErrorException(Token t, string format, params object[] args)
 		internal SyntaxErrorException(Token t, string format, params object[] args)
 			: base(format, args)
 			: base(format, args)
 		{
 		{

+ 2 - 1
src/MoonSharp.Interpreter/MoonSharp.Interpreter.net35-client.csproj

@@ -226,7 +226,7 @@
     <Compile Include="Loaders\EmbeddedResourcesScriptLoader.cs" />
     <Compile Include="Loaders\EmbeddedResourcesScriptLoader.cs" />
     <Compile Include="Loaders\FileSystemScriptLoader.cs" />
     <Compile Include="Loaders\FileSystemScriptLoader.cs" />
     <Compile Include="Loaders\InvalidScriptLoader.cs" />
     <Compile Include="Loaders\InvalidScriptLoader.cs" />
-    <Compile Include="Loaders\ReplInterpreterScriptLoader.cs" />
+    <Compile Include="REPL\ReplInterpreterScriptLoader.cs" />
     <Compile Include="Loaders\ScriptLoaderBase.cs" />
     <Compile Include="Loaders\ScriptLoaderBase.cs" />
     <Compile Include="Loaders\IScriptLoader.cs" />
     <Compile Include="Loaders\IScriptLoader.cs" />
     <Compile Include="Loaders\UnityAssetsScriptLoader.cs" />
     <Compile Include="Loaders\UnityAssetsScriptLoader.cs" />
@@ -242,6 +242,7 @@
     <Compile Include="Platforms\PortableWrappers\Attributes.cs" />
     <Compile Include="Platforms\PortableWrappers\Attributes.cs" />
     <Compile Include="Platforms\PortableWrappers\ExtensionMethods.cs" />
     <Compile Include="Platforms\PortableWrappers\ExtensionMethods.cs" />
     <Compile Include="Platforms\PortableWrappers\Stopwatch.cs" />
     <Compile Include="Platforms\PortableWrappers\Stopwatch.cs" />
+    <Compile Include="REPL\ReplInterpreter.cs" />
     <Compile Include="Script.cs" />
     <Compile Include="Script.cs" />
     <Compile Include="DataTypes\Table.cs" />
     <Compile Include="DataTypes\Table.cs" />
     <Compile Include="Execution\VM\ByteCode.cs" />
     <Compile Include="Execution\VM\ByteCode.cs" />

+ 1 - 1
src/MoonSharp.Interpreter/Platforms/IPlatformAccessor.cs

@@ -57,7 +57,7 @@ namespace MoonSharp.Interpreter.Platforms
 		/// If a meaningful implementation cannot be provided, this method should return null.
 		/// If a meaningful implementation cannot be provided, this method should return null.
 		/// </summary>
 		/// </summary>
 		/// <returns></returns>
 		/// <returns></returns>
-		string DefaultInput();
+		string DefaultInput(string prompt);
 
 
 		/// <summary>
 		/// <summary>
 		/// A function used to open files in the 'io' module.
 		/// A function used to open files in the 'io' module.

+ 16 - 0
src/MoonSharp.Interpreter/Platforms/PlatformAccessorBase.cs

@@ -60,15 +60,31 @@ namespace MoonSharp.Interpreter.Platforms
 		public abstract void DefaultPrint(string content);
 		public abstract void DefaultPrint(string content);
 
 
 		/// <summary>
 		/// <summary>
+		/// DEPRECATED.
+		/// This is kept for backward compatibility, see the overload taking a prompt as an input parameter.
+		/// 
 		/// Default handler for interactive line input calls. Can be customized in ScriptOptions.
 		/// Default handler for interactive line input calls. Can be customized in ScriptOptions.
 		/// If an inheriting class whants to give a meaningful implementation, this method MUST be overridden.
 		/// If an inheriting class whants to give a meaningful implementation, this method MUST be overridden.
 		/// </summary>
 		/// </summary>
 		/// <returns>null</returns>
 		/// <returns>null</returns>
+		[Obsolete("Replace with DefaultInput(string)")]
 		public virtual string DefaultInput()
 		public virtual string DefaultInput()
 		{
 		{
 			return null;
 			return null;
 		}
 		}
 
 
+		/// <summary>
+		/// Default handler for interactive line input calls. Can be customized in ScriptOptions.
+		/// If an inheriting class whants to give a meaningful implementation, this method MUST be overridden.
+		/// </summary>
+		/// <returns>null</returns>
+		public virtual string DefaultInput(string prompt)
+		{
+#pragma warning disable 618
+			return DefaultInput();
+#pragma warning restore 618
+		}
+
 		/// <summary>
 		/// <summary>
 		/// A function used to open files in the 'io' module. 
 		/// A function used to open files in the 'io' module. 
 		/// Can have an invalid implementation if 'io' module is filtered out.
 		/// Can have an invalid implementation if 'io' module is filtered out.

+ 1 - 1
src/MoonSharp.Interpreter/Properties/AssemblyInfo.cs

@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("http://www.moonsharp.org")]
 [assembly: AssemblyCompany("http://www.moonsharp.org")]
 [assembly: AssemblyProduct("MoonSharp.Interpreter")]
 [assembly: AssemblyProduct("MoonSharp.Interpreter")]
-[assembly: AssemblyCopyright("Copyright © 2014, Marco Mastropaolo")]
+[assembly: AssemblyCopyright("Copyright © 2014-2015, Marco Mastropaolo")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 [assembly: AssemblyCulture("")]
 
 

+ 120 - 0
src/MoonSharp.Interpreter/REPL/ReplInterpreter.cs

@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MoonSharp.Interpreter.REPL
+{
+	/// <summary>
+	/// This class provides a simple REPL intepreter ready to be reused in a simple way.
+	/// </summary>
+	public class ReplInterpreter
+	{
+		Script m_Script;
+		string m_CurrentCommand = string.Empty;
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="ReplInterpreter"/> class.
+		/// </summary>
+		/// <param name="script">The script.</param>
+		public ReplInterpreter(Script script)
+		{
+			this.m_Script = script;
+		}
+
+		/// <summary>
+		/// Gets or sets a value indicating whether this instances handle inputs starting with a "?" as a 
+		/// dynamic expression to evaluate instead of script code (likely invalid)
+		/// </summary>
+		public bool HandleDynamicExprs { get; set; }
+
+		/// <summary>
+		/// Gets or sets a value indicating whether this instances handle inputs starting with a "=" as a 
+		/// non-dynamic expression to evaluate (just like the Lua interpreter does by default).
+		/// </summary>
+		public bool HandleClassicExprsSyntax { get; set; }
+
+		/// <summary>
+		/// Gets a value indicating whether this instance has a pending command 
+		/// </summary>
+		public bool HasPendingCommand { get { return m_CurrentCommand.Length > 0; } }
+
+		/// <summary>
+		/// Gets the current pending command.
+		/// </summary>
+		public string CurrentPendingCommand { get { return m_CurrentCommand; } }
+
+		/// <summary>
+		/// Gets the classic prompt (">" or ">>") given the current state of the interpreter
+		/// </summary>
+		public string ClassicPrompt { get { return HasPendingCommand ? ">>" : ">"; } }
+
+		/// <summary>
+		/// Executes a REPL command.
+		/// This method returns the result of the computation, or null if more input is needed for a computation.
+		/// In case of errors, exceptions are propagated to the caller.
+		/// </summary>
+		/// <param name="input">The input.</param>
+		/// <returns>This method returns the result of the computation, or null if more input is needed for a computation.</returns>
+		public DynValue ExecuteRepl(string input)
+		{
+			bool isFirstLine = !HasPendingCommand;
+
+			bool forced = (input == "");
+
+			m_CurrentCommand += input;
+
+			if (m_CurrentCommand.Length == 0)
+				return DynValue.Void;
+
+			m_CurrentCommand += "\n";
+
+			try
+			{
+				DynValue result = null;
+
+				if (isFirstLine && HandleClassicExprsSyntax && m_CurrentCommand.StartsWith("="))
+				{
+					m_CurrentCommand = "return " + m_CurrentCommand.Substring(1); 
+				}
+				
+				if (isFirstLine && HandleDynamicExprs && m_CurrentCommand.StartsWith("?"))
+				{
+					var code = m_CurrentCommand.Substring(1);
+					var exp = m_Script.CreateDynamicExpression(code);
+					result = exp.Evaluate();
+				}
+				else
+				{
+					var v = m_Script.LoadString(m_CurrentCommand, null, "stdin");
+					result = m_Script.Call(v);
+				}
+
+				m_CurrentCommand = "";
+				return result;
+			}
+			catch (SyntaxErrorException ex)
+			{
+				if (forced || !ex.IsPrematureStreamTermination)
+				{
+					m_CurrentCommand = "";
+					throw;
+				}
+				else
+				{
+					return null;
+				}
+			}
+			catch (ScriptRuntimeException)
+			{
+				m_CurrentCommand = "";
+				throw;
+			}
+			catch (Exception)
+			{
+				m_CurrentCommand = "";
+				throw;
+			}
+		}
+	}
+}

+ 2 - 1
src/MoonSharp.Interpreter/Loaders/ReplInterpreterScriptLoader.cs → src/MoonSharp.Interpreter/REPL/ReplInterpreterScriptLoader.cs

@@ -3,8 +3,9 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
+using MoonSharp.Interpreter.Loaders;
 
 
-namespace MoonSharp.Interpreter.Loaders
+namespace MoonSharp.Interpreter.REPL
 {
 {
 	/// <summary>
 	/// <summary>
 	/// A script loader loading scripts directly from the file system (does not go through platform object)
 	/// A script loader loading scripts directly from the file system (does not go through platform object)

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

@@ -52,7 +52,7 @@ namespace MoonSharp.Interpreter
 			DefaultOptions = new ScriptOptions()
 			DefaultOptions = new ScriptOptions()
 			{
 			{
 				DebugPrint = s => { Script.GlobalOptions.Platform.DefaultPrint(s); },
 				DebugPrint = s => { Script.GlobalOptions.Platform.DefaultPrint(s); },
-				DebugInput = () => { return Script.GlobalOptions.Platform.DefaultInput(); },
+				DebugInput = s => { return Script.GlobalOptions.Platform.DefaultInput(s); },
 				CheckThreadAccess = true,
 				CheckThreadAccess = true,
 				ScriptLoader = PlatformAutoDetector.GetDefaultScriptLoader(),
 				ScriptLoader = PlatformAutoDetector.GetDefaultScriptLoader(),
 				TailCallOptimizationThreshold = 65536
 				TailCallOptimizationThreshold = 65536

+ 2 - 2
src/MoonSharp.Interpreter/ScriptOptions.cs

@@ -45,9 +45,9 @@ namespace MoonSharp.Interpreter
 		public Action<string> DebugPrint { get; set; }
 		public Action<string> DebugPrint { get; set; }
 
 
 		/// <summary>
 		/// <summary>
-		/// Gets or sets the debug input handler
+		/// Gets or sets the debug input handler (takes a prompt as an input, for interactive interpreters, like debug.debug).
 		/// </summary>
 		/// </summary>
-		public Func<string> DebugInput { get; set; }
+		public Func<string, string> DebugInput { get; set; }
 
 
 		/// <summary>
 		/// <summary>
 		/// Gets or sets a value indicating whether error messages will use Lua error locations instead of MoonSharp 
 		/// Gets or sets a value indicating whether error messages will use Lua error locations instead of MoonSharp 

+ 5 - 1
src/MoonSharp.Interpreter/Tree/Expression_.cs

@@ -228,7 +228,11 @@ namespace MoonSharp.Interpreter.Tree
 				case TokenType.Name:
 				case TokenType.Name:
 					return new SymbolRefExpression(T, lcontext);
 					return new SymbolRefExpression(T, lcontext);
 				default:
 				default:
-					throw new SyntaxErrorException(T, "unexpected symbol near '{0}'", T.Text);
+					throw new SyntaxErrorException(T, "unexpected symbol near '{0}'", T.Text)
+					{
+						IsPrematureStreamTermination = (T.Type == TokenType.Eof)
+					};
+
 			}
 			}
 		}
 		}
 
 

+ 4 - 1
src/MoonSharp.Interpreter/Tree/Expressions/FunctionCallExpression.cs

@@ -61,7 +61,10 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 					}
 					}
 					break;
 					break;
 				default:
 				default:
-					throw new SyntaxErrorException(lcontext.Lexer.Current, "function arguments expected");
+					throw new SyntaxErrorException(lcontext.Lexer.Current, "function arguments expected")
+					{
+						IsPrematureStreamTermination = (lcontext.Lexer.Current.Type == TokenType.Eof)
+					};
 			}
 			}
 		}
 		}
 
 

+ 5 - 2
src/MoonSharp.Interpreter/Tree/Expressions/FunctionDefinitionExpression.cs

@@ -77,7 +77,10 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 			Statement s = new CompositeStatement(lcontext);
 			Statement s = new CompositeStatement(lcontext);
 
 
 			if (lcontext.Lexer.Current.Type != TokenType.End)
 			if (lcontext.Lexer.Current.Type != TokenType.End)
-				throw new SyntaxErrorException(lcontext.Lexer.Current, "'end' expected near '{0}'", lcontext.Lexer.Current.Text);
+				throw new SyntaxErrorException(lcontext.Lexer.Current, "'end' expected near '{0}'", lcontext.Lexer.Current.Text)
+				{
+					IsPrematureStreamTermination = (lcontext.Lexer.Current.Type == TokenType.Eof)
+				};
 
 
 			m_End = lcontext.Lexer.Current.GetSourceRef();
 			m_End = lcontext.Lexer.Current.GetSourceRef();
 
 
@@ -107,7 +110,7 @@ namespace MoonSharp.Interpreter.Tree.Expressions
 					paramnames.Add(WellKnownSymbols.VARARGS);
 					paramnames.Add(WellKnownSymbols.VARARGS);
 				}
 				}
 				else
 				else
-					throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
+					UnexpectedTokenType(t);
 
 
 				lcontext.Lexer.Next();
 				lcontext.Lexer.Next();
 
 

+ 10 - 4
src/MoonSharp.Interpreter/Tree/Lexer/Lexer.cs

@@ -230,6 +230,11 @@ namespace MoonSharp.Interpreter.Tree
 				case '"':
 				case '"':
 				case '\'':
 				case '\'':
 					return ReadSimpleStringToken(fromLine, fromCol);
 					return ReadSimpleStringToken(fromLine, fromCol);
+				case '\0':
+					throw new SyntaxErrorException(CreateToken(TokenType.Invalid, fromLine, fromCol), "unexpected symbol near '{0}'", CursorChar())
+					{
+						IsPrematureStreamTermination = true
+					};
 				default:
 				default:
 					{
 					{
 						if (char.IsLetter(c) || c == '_')
 						if (char.IsLetter(c) || c == '_')
@@ -242,6 +247,7 @@ namespace MoonSharp.Interpreter.Tree
 							return ReadNumberToken(fromLine, fromCol);
 							return ReadNumberToken(fromLine, fromCol);
 						}
 						}
 					}
 					}
+
 					throw new SyntaxErrorException(CreateToken(TokenType.Invalid, fromLine, fromCol), "unexpected symbol near '{0}'", CursorChar());
 					throw new SyntaxErrorException(CreateToken(TokenType.Invalid, fromLine, fromCol), "unexpected symbol near '{0}'", CursorChar());
 			}
 			}
 
 
@@ -263,7 +269,7 @@ namespace MoonSharp.Interpreter.Tree
 					{
 					{
 						throw new SyntaxErrorException(
 						throw new SyntaxErrorException(
 							CreateToken(TokenType.Invalid, fromLine, fromCol),
 							CreateToken(TokenType.Invalid, fromLine, fromCol),
-							"unfinished long {0} near '<eof>'", subtypeforerrors);
+							"unfinished long {0} near '<eof>'", subtypeforerrors) { IsPrematureStreamTermination = true };
 					}
 					}
 					else if (c == '=')
 					else if (c == '=')
 					{
 					{
@@ -278,7 +284,7 @@ namespace MoonSharp.Interpreter.Tree
 					{
 					{
 						throw new SyntaxErrorException(
 						throw new SyntaxErrorException(
 							CreateToken(TokenType.Invalid, fromLine, fromCol),
 							CreateToken(TokenType.Invalid, fromLine, fromCol),
-							"invalid long {0} delimiter near '{1}'", subtypeforerrors, c);
+							"invalid long {0} delimiter near '{1}'", subtypeforerrors, c) { IsPrematureStreamTermination = true };
 					}
 					}
 				}
 				}
 			}
 			}
@@ -297,7 +303,7 @@ namespace MoonSharp.Interpreter.Tree
 				{
 				{
 					throw new SyntaxErrorException(
 					throw new SyntaxErrorException(
 							CreateToken(TokenType.Invalid, fromLine, fromCol),
 							CreateToken(TokenType.Invalid, fromLine, fromCol),
-							"unfinished long {0} near '{1}'", subtypeforerrors, text.ToString());
+							"unfinished long {0} near '{1}'", subtypeforerrors, text.ToString()) { IsPrematureStreamTermination = true };
 				}
 				}
 				else if (c == ']' && CursorMatches(end_pattern))
 				else if (c == ']' && CursorMatches(end_pattern))
 				{
 				{
@@ -505,7 +511,7 @@ namespace MoonSharp.Interpreter.Tree
 
 
 			throw new SyntaxErrorException(
 			throw new SyntaxErrorException(
 				CreateToken(TokenType.Invalid, fromLine, fromCol),
 				CreateToken(TokenType.Invalid, fromLine, fromCol),
-				"unfinished string near '{0}'", text.ToString());
+				"unfinished string near '{0}'", text.ToString()) { IsPrematureStreamTermination = true };
 		}
 		}
 
 
 		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)

+ 19 - 20
src/MoonSharp.Interpreter/Tree/NodeBase.cs

@@ -21,39 +21,33 @@ namespace MoonSharp.Interpreter.Tree
 
 
 		public abstract void Compile(ByteCode bc);
 		public abstract void Compile(ByteCode bc);
 
 
-		//protected SourceRef BuildSourceRef(IToken token, ITerminalNode terminalNode)
-		//{
-		//	return RegisterSourceRef(new SourceRef(LoadingContext.Source.SourceID, token.Column, token.Column + terminalNode.GetText().Length, token.Line, token.Line, true));
-		//}
-
-		//protected SourceRef BuildSourceRef(IToken token1, IToken token2 = null)
-		//{
-		//	token2 = token2 ?? token1;
-		//	return RegisterSourceRef(new SourceRef(LoadingContext.Source.SourceID, token1.Column, token2.Column + token2.Text.Length, token1.Line, token2.Line, true));
-		//}
-
-		//protected SourceRef BuildSourceRef(ITerminalNode terminalNode)
-		//{
-		//	return BuildSourceRef(terminalNode.Symbol, terminalNode);
-		//}
 
 
+		protected static Token UnexpectedTokenType(Token t)
+		{
+			throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text)
+			{
+				IsPrematureStreamTermination = (t.Type == TokenType.Eof)
+			};
+		}
 
 
 		protected static Token CheckTokenType(ScriptLoadingContext lcontext, TokenType tokenType)
 		protected static Token CheckTokenType(ScriptLoadingContext lcontext, TokenType tokenType)
 		{
 		{
 			Token t = lcontext.Lexer.Current;
 			Token t = lcontext.Lexer.Current;
 			if (t.Type != tokenType)
 			if (t.Type != tokenType)
-				throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
+				return UnexpectedTokenType(t);
 
 
 			lcontext.Lexer.Next();
 			lcontext.Lexer.Next();
 
 
 			return t;
 			return t;
 		}
 		}
 
 
+
+
 		protected static Token CheckTokenType(ScriptLoadingContext lcontext, TokenType tokenType1, TokenType tokenType2)
 		protected static Token CheckTokenType(ScriptLoadingContext lcontext, TokenType tokenType1, TokenType tokenType2)
 		{
 		{
 			Token t = lcontext.Lexer.Current;
 			Token t = lcontext.Lexer.Current;
 			if (t.Type != tokenType1 && t.Type != tokenType2)
 			if (t.Type != tokenType1 && t.Type != tokenType2)
-				throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
+				return UnexpectedTokenType(t);
 
 
 			lcontext.Lexer.Next();
 			lcontext.Lexer.Next();
 
 
@@ -63,7 +57,7 @@ namespace MoonSharp.Interpreter.Tree
 		{
 		{
 			Token t = lcontext.Lexer.Current;
 			Token t = lcontext.Lexer.Current;
 			if (t.Type != tokenType1 && t.Type != tokenType2 && t.Type != tokenType3)
 			if (t.Type != tokenType1 && t.Type != tokenType2 && t.Type != tokenType3)
-				throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
+				return UnexpectedTokenType(t);
 
 
 			lcontext.Lexer.Next();
 			lcontext.Lexer.Next();
 
 
@@ -74,16 +68,21 @@ namespace MoonSharp.Interpreter.Tree
 		{
 		{
 			Token t = lcontext.Lexer.Current;
 			Token t = lcontext.Lexer.Current;
 			if (t.Type != tokenType)
 			if (t.Type != tokenType)
-				throw new SyntaxErrorException(t, "unexpected symbol near '{0}'", t.Text);
+				UnexpectedTokenType(t);
 		}
 		}
 
 
 		protected static Token CheckMatch(ScriptLoadingContext lcontext, Token originalToken, TokenType expectedTokenType, string expectedTokenText)
 		protected static Token CheckMatch(ScriptLoadingContext lcontext, Token originalToken, TokenType expectedTokenType, string expectedTokenText)
 		{
 		{
 			Token t = lcontext.Lexer.Current;
 			Token t = lcontext.Lexer.Current;
 			if (t.Type != expectedTokenType)
 			if (t.Type != expectedTokenType)
+			{
 				throw new SyntaxErrorException(lcontext.Lexer.Current,
 				throw new SyntaxErrorException(lcontext.Lexer.Current,
 					"'{0}' expected (to close '{1}' at line {2}) near '{3}'",
 					"'{0}' expected (to close '{1}' at line {2}) near '{3}'",
-					expectedTokenText, originalToken.Text, originalToken.FromLine, t.Text);
+					expectedTokenText, originalToken.Text, originalToken.FromLine, t.Text)
+										{
+											IsPrematureStreamTermination = (t.Type == TokenType.Eof)
+										};
+			}
 
 
 			lcontext.Lexer.Next();
 			lcontext.Lexer.Next();
 
 

+ 2 - 2
src/MoonSharp.Interpreter/Tree/Statements/FunctionDefinitionStatement.cs

@@ -55,9 +55,9 @@ namespace MoonSharp.Interpreter.Tree.Statements
 					while (lcontext.Lexer.Current.Type != TokenType.Brk_Open_Round)
 					while (lcontext.Lexer.Current.Type != TokenType.Brk_Open_Round)
 					{
 					{
 						Token separator = lcontext.Lexer.Current;
 						Token separator = lcontext.Lexer.Current;
-	
+
 						if (separator.Type != TokenType.Colon && separator.Type != TokenType.Dot)
 						if (separator.Type != TokenType.Colon && separator.Type != TokenType.Dot)
-							throw new SyntaxErrorException(separator, "unexpected symbol near '{0}'", separator.Text);
+							UnexpectedTokenType(separator);
 						
 						
 						lcontext.Lexer.Next();
 						lcontext.Lexer.Next();
 
 

+ 1 - 1
src/MoonSharp.RemoteDebugger/Properties/AssemblyInfo.cs

@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("http://www.moonsharp.org")]
 [assembly: AssemblyCompany("http://www.moonsharp.org")]
 [assembly: AssemblyProduct("MoonSharp.Debugger")]
 [assembly: AssemblyProduct("MoonSharp.Debugger")]
-[assembly: AssemblyCopyright("Copyright © 2014, Marco Mastropaolo")]
+[assembly: AssemblyCopyright("Copyright © 2014-2015, Marco Mastropaolo")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 [assembly: AssemblyCulture("")]
 
 

+ 24 - 50
src/MoonSharp/Program.cs

@@ -8,6 +8,7 @@ using System.Text;
 using MoonSharp.Interpreter;
 using MoonSharp.Interpreter;
 using MoonSharp.Interpreter.Execution;
 using MoonSharp.Interpreter.Execution;
 using MoonSharp.Interpreter.Loaders;
 using MoonSharp.Interpreter.Loaders;
+using MoonSharp.Interpreter.REPL;
 using MoonSharp.RemoteDebugger;
 using MoonSharp.RemoteDebugger;
 using MoonSharp.RemoteDebugger.Network;
 using MoonSharp.RemoteDebugger.Network;
 
 
@@ -23,11 +24,8 @@ namespace MoonSharp
 			Script.DefaultOptions.ScriptLoader = new ReplInterpreterScriptLoader();
 			Script.DefaultOptions.ScriptLoader = new ReplInterpreterScriptLoader();
 
 
 			Console.WriteLine("MoonSharp REPL {0} [{1}]", Script.VERSION, Script.GlobalOptions.Platform.GetPlatformName());
 			Console.WriteLine("MoonSharp REPL {0} [{1}]", Script.VERSION, Script.GlobalOptions.Platform.GetPlatformName());
-			Console.WriteLine("Copyright (C) 2014 Marco Mastropaolo");
+			Console.WriteLine("Copyright (C) 2014-2015 Marco Mastropaolo");
 			Console.WriteLine("http://www.moonsharp.org");
 			Console.WriteLine("http://www.moonsharp.org");
-			Console.WriteLine("Based on Lua 5.1 - 5.3, Copyright (C) 1994-2014 Lua.org");
-			Console.WriteLine("License: https://raw.githubusercontent.com/xanathar/moonsharp/master/LICENSE");
-
 			Console.WriteLine();
 			Console.WriteLine();
 
 
 			if (args.Length == 1)
 			if (args.Length == 1)
@@ -37,65 +35,43 @@ namespace MoonSharp
 				script.DoFile(args[0]);
 				script.DoFile(args[0]);
 
 
 				Console.WriteLine("Done.");
 				Console.WriteLine("Done.");
-				
+
 				if (System.Diagnostics.Debugger.IsAttached)
 				if (System.Diagnostics.Debugger.IsAttached)
 					Console.ReadKey();
 					Console.ReadKey();
 			}
 			}
 			else
 			else
 			{
 			{
-				Console.WriteLine("Type <enter> twice to execute code.\n");
-				Console.WriteLine("Type !help to see help.");
+				Console.WriteLine("Type Lua code to execute it or type !help to see help on commands.\n");
+				Console.WriteLine("Welcome.\n");
 
 
 				Script script = new Script(CoreModules.Preset_Complete);
 				Script script = new Script(CoreModules.Preset_Complete);
 
 
-				string cmd = "";
+				ReplInterpreter interpreter = new ReplInterpreter(script)
+				{
+					HandleDynamicExprs = true,
+					HandleClassicExprsSyntax = true
+				};
 
 
 				while (true)
 				while (true)
 				{
 				{
-					Console.Write("{0}> ", string.IsNullOrEmpty(cmd) ? "" : ">");
+					Console.Write(interpreter.ClassicPrompt + " ");
+
 					string s = Console.ReadLine();
 					string s = Console.ReadLine();
 
 
-					if (s.StartsWith("!"))
+					if (!interpreter.HasPendingCommand && s.StartsWith("!"))
 					{
 					{
 						ParseCommand(script, s.Substring(1));
 						ParseCommand(script, s.Substring(1));
 						continue;
 						continue;
 					}
 					}
 
 
-					if (s != "")
-					{
-						cmd += s + "\n";
-						continue;
-					}
-
-					if (cmd.Length == 0)
-						continue;
-
-					//Console.WriteLine("=====");
-					//Console.WriteLine("{0}", cmd);
-					//Console.WriteLine("=====");
-
-					if (cmd == "exit")
-						return;
-
 					try
 					try
 					{
 					{
-						DynValue result = null;
-
-						if (cmd.StartsWith("?"))
-						{
-							var code = cmd.Substring(1);
-							var exp = script.CreateDynamicExpression(code);
-							result = exp.Evaluate();
-						}
-						else
-						{
-							var v = script.LoadString(cmd, null, "stdin");
-							result = script.Call(v);
-						}
-
-						Console.WriteLine("={0}", result);
+						DynValue result = interpreter.ExecuteRepl(s);
+
+						if (result != null && result.Type != DataType.Void)
+							Console.WriteLine("{0}", result);
 					}
 					}
-					catch (ScriptRuntimeException ex)
+					catch (InterpreterException ex)
 					{
 					{
 						Console.WriteLine("{0}", ex.DecoratedMessage ?? ex.Message);
 						Console.WriteLine("{0}", ex.DecoratedMessage ?? ex.Message);
 					}
 					}
@@ -103,14 +79,7 @@ namespace MoonSharp
 					{
 					{
 						Console.WriteLine("{0}", ex.Message);
 						Console.WriteLine("{0}", ex.Message);
 					}
 					}
-
-					cmd = "";
-
 				}
 				}
-
-
-
-
 			}
 			}
 		}
 		}
 
 
@@ -120,16 +89,21 @@ namespace MoonSharp
 		{
 		{
 			if (p == "help")
 			if (p == "help")
 			{
 			{
-				Console.WriteLine("Type Lua code followed by two <enter> keystrokes to execute Lua code, ");
+				Console.WriteLine("Type Lua code to execute Lua code, multilines are accepted, ");
 				Console.WriteLine("or type one of the following commands to execute them.");
 				Console.WriteLine("or type one of the following commands to execute them.");
 				Console.WriteLine("");
 				Console.WriteLine("");
 				Console.WriteLine("Commands:");
 				Console.WriteLine("Commands:");
 				Console.WriteLine("");
 				Console.WriteLine("");
+				Console.WriteLine("	!exit - Exits the interpreter");
 				Console.WriteLine("	!debug - Starts the debugger");
 				Console.WriteLine("	!debug - Starts the debugger");
 				Console.WriteLine("	!run <filename> - Executes the specified Lua script");
 				Console.WriteLine("	!run <filename> - Executes the specified Lua script");
 				Console.WriteLine("	!compile <filename> - Compiles the file in a binary format");
 				Console.WriteLine("	!compile <filename> - Compiles the file in a binary format");
 				Console.WriteLine("");
 				Console.WriteLine("");
 			}
 			}
+			else if (p == "exit")
+			{
+				Environment.Exit(0);
+			}
 			else if (p == "debug" && m_Debugger == null)
 			else if (p == "debug" && m_Debugger == null)
 			{
 			{
 				m_Debugger = new RemoteDebuggerService();
 				m_Debugger = new RemoteDebuggerService();

+ 1 - 1
src/MoonSharp/Properties/AssemblyInfo.cs

@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("http://www.moonsharp.org")]
 [assembly: AssemblyCompany("http://www.moonsharp.org")]
 [assembly: AssemblyProduct("MoonSharp")]
 [assembly: AssemblyProduct("MoonSharp")]
-[assembly: AssemblyCopyright("Copyright ©  2014, Marco Mastropaolo")]
+[assembly: AssemblyCopyright("Copyright © 2014-2015, Marco Mastropaolo")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 [assembly: AssemblyCulture("")]