diff --git a/DScript.Demo/testscript.js b/DScript.Demo/testscript.js index af89758..510d67c 100644 --- a/DScript.Demo/testscript.js +++ b/DScript.Demo/testscript.js @@ -1,12 +1,12 @@ -var MyClass = { - doSomethingComplicated: function (x, y) { - this.doSomethingElse(x, y); - }, - - doSomethingElse: function (a,b) { - - return Math.pow(--a, ++b) / 10.0; - } +const testStr = "For more information, see Chapter 3.4.5.1"; + +function MyClass() { + this.doSomethingComplicated = function (x, y) { + return this.doSomethingElse(x, y); + }; + this.doSomethingElse = function (a, b) { + return Math.pow(a, b) / 10.0; + }; }; var inst = new MyClass(); @@ -17,7 +17,7 @@ console.log(x); var to = typeof x; var p = to == "number" ? "yes" : "no"; -var testString = "For more information, see Chapter 3.4.5.1"; +var testString = testStr; var myRegex = /see (chapter \d+(\.\d)*)/i; var matches = testString.match(myRegex); @@ -38,11 +38,10 @@ catch (ex) { } try { - - var x = 1; + testStr = "123"; } catch (ex) { - + console.log(ex); } finally { diff --git a/DScript/ScriptEngine.Statement.cs b/DScript/ScriptEngine.Statement.cs index b7c0192..4c7ceee 100644 --- a/DScript/ScriptEngine.Statement.cs +++ b/DScript/ScriptEngine.Statement.cs @@ -38,19 +38,21 @@ private void Statement(ref bool execute) //allow for multiple semi colon such as ;;; currentLexer.Match((ScriptLex.LexTypes)';'); } - else if (currentLexer.TokenType == ScriptLex.LexTypes.RVar) + else if (currentLexer.TokenType == ScriptLex.LexTypes.RVar || currentLexer.TokenType == ScriptLex.LexTypes.RConst) { //creating variables //TODO: make this less shit - currentLexer.Match(ScriptLex.LexTypes.RVar); + var readOnly = currentLexer.TokenType == ScriptLex.LexTypes.RConst; + + currentLexer.Match(currentLexer.TokenType); while (currentLexer.TokenType != (ScriptLex.LexTypes)';') { ScriptVarLink a = null; if (execute) { - a = scopes.Back().FindChildOrCreate(currentLexer.TokenString); + a = scopes.Back().FindChildOrCreate(currentLexer.TokenString, ScriptVar.Flags.Undefined, readOnly); } currentLexer.Match(ScriptLex.LexTypes.Id); diff --git a/DScript/ScriptEngine.cs b/DScript/ScriptEngine.cs index 68ba97d..29de250 100644 --- a/DScript/ScriptEngine.cs +++ b/DScript/ScriptEngine.cs @@ -118,19 +118,20 @@ public void Execute(string code) { Statement(ref execute); } - catch (ScriptException ex) + catch (Exception ex) { - var errorMessage = new StringBuilder(string.Format("ERROR on line {0} column {1} [{2}]", currentLexer.LineNumber, currentLexer.ColumnNumber, ex.Message)); + if (ex is ScriptException || ex is JITException) + { + var errorMessage = new StringBuilder(string.Format("ERROR on line {0} column {1} [{2}]", currentLexer.LineNumber, currentLexer.ColumnNumber, ex.Message)); + + Console.Error.WriteLine(errorMessage.ToString()); - int i = 0; - foreach (ScriptVar scriptVar in scopes) + return; + } + else { - errorMessage.AppendLine(); - errorMessage.Append(i++ + ": " + scriptVar); + throw; } - - Console.Error.WriteLine(errorMessage.ToString()); - throw; } } } diff --git a/DScript/ScriptLex.cs b/DScript/ScriptLex.cs index e6b7242..5fa0b47 100644 --- a/DScript/ScriptLex.cs +++ b/DScript/ScriptLex.cs @@ -130,6 +130,7 @@ public enum LexTypes RCatch, RFinally, RThrow, + RConst, RListEnd } @@ -257,6 +258,7 @@ public void GetNextToken() case "catch": TokenType = LexTypes.RCatch; break; case "finally": TokenType = LexTypes.RFinally; break; case "throw": TokenType = LexTypes.RThrow; break; + case "const": TokenType = LexTypes.RConst; break; } } else if (CurrentChar.IsNumeric()) //Numbers diff --git a/DScript/ScriptVar.cs b/DScript/ScriptVar.cs index cb9d380..4e8fafc 100644 --- a/DScript/ScriptVar.cs +++ b/DScript/ScriptVar.cs @@ -440,12 +440,12 @@ public ScriptVarLink FindChild(string childName) return null; } - public ScriptVarLink FindChildOrCreate(string childName, Flags varFlags = Flags.Undefined) + public ScriptVarLink FindChildOrCreate(string childName, Flags varFlags = Flags.Undefined, bool readOnly = false) { var l = FindChild(childName); if (l != null) return l; - return AddChild(childName, new ScriptVar(null, varFlags)); + return AddChild(childName, new ScriptVar(null, varFlags), readOnly); } public ScriptVarLink FindChildOrCreateByPath(string path) @@ -458,7 +458,7 @@ public ScriptVarLink FindChildOrCreateByPath(string path) return FindChildOrCreate(parts[0], Flags.Object).Var.FindChildOrCreateByPath(parts[1]); } - public ScriptVarLink AddChild(string childName, ScriptVar child) + public ScriptVarLink AddChild(string childName, ScriptVar child, bool readOnly = false) { if (IsUndefined) { @@ -467,7 +467,7 @@ public ScriptVarLink AddChild(string childName, ScriptVar child) var c = child ?? new ScriptVar(); - var link = new ScriptVarLink(c, childName) + var link = new ScriptVarLink(c, childName, readOnly) { Owned = true }; diff --git a/DScript/ScriptVarLink.cs b/DScript/ScriptVarLink.cs index 057f2f5..ab1f847 100644 --- a/DScript/ScriptVarLink.cs +++ b/DScript/ScriptVarLink.cs @@ -54,14 +54,16 @@ protected virtual void Dispose(bool disposing) public ScriptVarLink Prev { get; internal set; } public ScriptVar Var { get; internal set; } public bool Owned { get; internal set; } + public bool IsConst { get; private set; } - public ScriptVarLink(ScriptVar var, string name) + public ScriptVarLink(ScriptVar var, string name, bool readOnly = false) { Name = name; Var = var.Ref(); Next = null; Prev = null; Owned = false; + IsConst = readOnly; } public ScriptVarLink(ScriptVarLink toCopy) @@ -75,6 +77,11 @@ public ScriptVarLink(ScriptVarLink toCopy) public void ReplaceWith(ScriptVar newVar) { + if(IsConst && Var?.IsUndefined == false) + { + throw new JITException(string.Format("{0} is const, cannot assign a new value", Name)); + } + var oldVar = Var; Var = newVar.Ref(); oldVar.UnRef(); @@ -82,6 +89,7 @@ public void ReplaceWith(ScriptVar newVar) public void ReplaceWith(ScriptVarLink newVar) { + ReplaceWith(newVar != null ? newVar.Var : new ScriptVar()); }