diff --git a/PublicTypes/RScriptVariables.cs b/PublicTypes/RScriptVariables.cs index bd4a110..3ce4cd7 100644 --- a/PublicTypes/RScriptVariables.cs +++ b/PublicTypes/RScriptVariables.cs @@ -25,15 +25,14 @@ namespace Convention.RScript internalData = value; return; } - internalData = Convert.ChangeType(value, type); + if (type == typeof(object) || type == value.GetType()) + internalData = value; + else + internalData = Convert.ChangeType(value, type); } } private object internalData; - public RScriptVariableEntry(object data) : this() - { - this.data = data; - } public RScriptVariableEntry(Type type, object data) : this() { this.type = type; diff --git a/RScriptContext.cs b/RScriptContext.cs index 22b41d2..c0fd6d0 100644 --- a/RScriptContext.cs +++ b/RScriptContext.cs @@ -169,6 +169,30 @@ namespace Convention.RScript } } + public class BuildInContext + { + private RScriptContext context; + public BuildInContext(RScriptContext context) + { + this.context = context; + } + + public bool ExistVar(string name) + { + return context.Variables.ContainsKey(name); + } + + public bool ExistNamespace(string name) + { + return context.NamespaceLabels.ContainsKey(name); + } + + public bool ExistLabel(string name) + { + return context.Labels.ContainsKey(name); + } + } + public RScriptContext(string[] expressions, RScriptImportClass import = null, RScriptVariables variables = null, @@ -177,6 +201,7 @@ namespace Convention.RScript { this.Import = import ?? new(); this.Variables = variables ?? new(); + this.Variables.Add("context", new(typeof(object), new BuildInContext(this))); this.Sentences = (from item in expressions select ParseToSentence(item)).ToArray(); if (matcher != null) this.SentenceParser = matcher; @@ -221,13 +246,26 @@ namespace Convention.RScript return result; } - public void Run(ExpressionParser parser) + private void BeforeRun(ExpressionParser parser) { CurrentLocalSpaceVariableNames.Clear(); RuntimePointerStack.Clear(); GotoPointerStack.Clear(); CurrentLocalSpaceVariableNames.Clear(); CurrentLocalSpaceVariableNames.Push(new()); + foreach (var staticType in Import) + { + parser.context.Imports.AddType(staticType); + } + foreach (var (name,varObject) in Variables) + { + parser.context.Variables[name] = varObject.data; + } + } + + public void Run(ExpressionParser parser) + { + BeforeRun(parser); for (CurrentRuntimePointer = 0; CurrentRuntimePointer < Sentences.Length; CurrentRuntimePointer++) { RunNextStep(parser); @@ -242,11 +280,7 @@ namespace Convention.RScript public IEnumerator RunAsync(ExpressionParser parser) { - CurrentLocalSpaceVariableNames.Clear(); - RuntimePointerStack.Clear(); - GotoPointerStack.Clear(); - CurrentLocalSpaceVariableNames.Clear(); - CurrentLocalSpaceVariableNames.Push(new()); + BeforeRun(parser); for (CurrentRuntimePointer = 0; CurrentRuntimePointer < Sentences.Length; CurrentRuntimePointer++) { var ret = RunNextStep(parser); diff --git a/RScriptEngine.cs b/RScriptEngine.cs index f3482be..3779c00 100644 --- a/RScriptEngine.cs +++ b/RScriptEngine.cs @@ -42,16 +42,16 @@ namespace Convention.RScript else if (c == '/' && i + 1 < e) { // Skip single-line comment - if (script[i + 1] == '/') + if (line[i + 1] == '/') { - while (i < script.Length && script[i] != '\n') + while (i < line.Length && line[i] != '\n') i++; } // Skip multi-line comment - else if (script[i + 1] == '*') + else if (line[i + 1] == '*') { i += 2; - while (i + 1 < script.Length && !(script[i] == '*' && script[i + 1] == '/')) + while (i + 1 < line.Length && !(line[i] == '*' && line[i + 1] == '/')) i++; i++; } @@ -63,23 +63,24 @@ namespace Convention.RScript else if (c == '#') { // Skip single-line comment - while (i < script.Length && script[i] != '\n') + while (i < line.Length && line[i] != '\n') i++; } else if (c == '\"') { + builder.Append(c); for (i++; i < e; i++) { - builder.Append(script[i]); - if (script[i] == '\"') + builder.Append(line[i]); + if (line[i] == '\"') { break; } - else if (script[i] == '\\') + else if (line[i] == '\\') { i++; if (i < e) - builder.Append(script[i]); + builder.Append(line[i]); else throw new RScriptCompileException("Invalid escape sequence in string literal", lineIndex, i); } @@ -90,14 +91,10 @@ namespace Convention.RScript PushBuilder(); statements.Add(c.ToString()); } - else if (string.Compare("namespace", 0, script, i, "namespace".Length) == 0) + else if (string.Compare("namespace", 0, line, i, "namespace".Length) == 0) { - builder.Append("namespace"); - i += "namespace".Length; - if (i >= e) - throw new RScriptCompileException("Invalid namespace declaration", lineIndex, i); - Regex regex = new(@"^\s*\([a-zA-Z_][a-zA-Z0-9_]*\)"); - var match = regex.Match(script, i); + Regex regex = new(@"^\s*namespace\s*\([a-zA-Z_][a-zA-Z0-9_]*\)"); + var match = regex.Match(line); if (match.Success) { builder.Append(match.Value); @@ -129,8 +126,6 @@ namespace Convention.RScript { parser = new(new()); context = new(SplitScript(script).ToArray(), import, variables); - foreach (var type in context.Import) - parser.context.Imports.AddType(type); context.Run(parser); return context.GetCurrentVariables(); } @@ -139,8 +134,6 @@ namespace Convention.RScript { parser = new(new()); context = new(SplitScript(script).ToArray(), import, variables); - foreach (var type in context.Import) - parser.context.Imports.AddType(type); return context.RunAsync(parser); } }