diff --git a/GraceLanguage/Execution/Interpreter.cs b/GraceLanguage/Execution/Interpreter.cs index 3e3bf36..cc0aa76 100644 --- a/GraceLanguage/Execution/Interpreter.cs +++ b/GraceLanguage/Execution/Interpreter.cs @@ -257,6 +257,34 @@ public void LoadExtensionsFromObject(GraceObject ext) ext.Request(this, req); GraceString.ExtendWith(req.InheritedMethods); } + req = MethodRequest.Nullary("BooleanExtension"); + req.IsInherits = true; + if (ext.RespondsTo(req)) + { + var uo = new UserObject(); + req.InheritingObject = uo; + ext.Request(this, req); + GraceBoolean.ExtendWith(req.InheritedMethods); + } + req = MethodRequest.Nullary("SequenceExtension"); + req.IsInherits = true; + if (ext.RespondsTo(req)) + { + var uo = new UserObject(); + req.InheritingObject = uo; + ext.Request(this, req); + Iterables.ExtendWith(req.InheritedMethods); + } + req = MethodRequest.Nullary("TypeExtension"); + req.IsInherits = true; + if (ext.RespondsTo(req)) + { + var uo = new UserObject(); + req.InheritingObject = uo; + ext.Request(this, req); + GraceType.ExtendWith(req.InheritedMethods); + } + } /// @@ -366,9 +394,11 @@ public GraceObject LoadModule(string path) continue; } filePath = Path.Combine(p, path + ".grace"); - mod = tryLoadModuleFile(filePath, path); - if (mod != null) + + String mod_contents = TryReadModuleFile(filePath, path); + if (mod_contents != null) { + mod = LoadModuleString(filePath, mod_contents); modules[path] = mod; return mod; } @@ -402,12 +432,14 @@ public GraceObject LoadModule(string path) return null; } - /// Load a module file if it exists - private GraceObject tryLoadModuleFile(string filePath, + /// Read a module file if it exists + /// Filesystem path to the module + /// Module name to treat this code as belonging to. + public String TryReadModuleFile(string filePath, string importPath) { return (File.Exists(filePath)) - ? loadModuleFile(filePath, importPath) + ? readModuleFile(filePath, importPath) : null; } @@ -429,13 +461,13 @@ private GraceObject tryLoadResource(string filePath, string importPath) : null; } - /// Load a module file - private GraceObject loadModuleFile(string filePath, string importPath) + /// Read a module file + private String readModuleFile(string filePath, string importPath) { Interpreter.Debug("========== LOAD " + filePath + " =========="); using (StreamReader reader = File.OpenText(filePath)) { - return LoadModuleString(importPath, reader.ReadToEnd()); + return reader.ReadToEnd(); } } @@ -670,7 +702,7 @@ public static GraceObject BaseTryCatchFinally(EvaluationContext ctx, /// public int NestRequest(string module, int line, string name) { - if (callStackMethod.Count > 511) { + if (callStackMethod.Count > 1023) { ErrorReporting.RaiseError(this, "R2024", new Dictionary(), "RecursionError: maximum call stack size exceeded." diff --git a/GraceLanguage/Parsing/ParseNodes.cs b/GraceLanguage/Parsing/ParseNodes.cs index e47c847..405bc6c 100644 --- a/GraceLanguage/Parsing/ParseNodes.cs +++ b/GraceLanguage/Parsing/ParseNodes.cs @@ -1953,15 +1953,15 @@ public override T Visit(ParseNodeVisitor visitor) /// public static class ParseNodeMeta { - private static Dictionary parseNodes; + private static DictionaryDataObject parseNodes; /// /// Get dictionary of parse node names to patterns. /// - public static Dictionary GetPatternDict() + public static GraceObject GetPatternDict() { if (parseNodes == null) - parseNodes = new Dictionary { + parseNodes = new DictionaryDataObject(new Dictionary { { "Object", new NativeTypePattern() }, { "MethodDeclaration", new NativeTypePattern() }, @@ -2021,7 +2021,7 @@ public static Dictionary GetPatternDict() new NativeTypePattern() }, { "Comment", new NativeTypePattern() }, - }; + }); return parseNodes; } @@ -2033,8 +2033,7 @@ private static GraceObject getPrettyPrinter(EvaluationContext ctx) string path = Path.Combine(dir, "pretty_printer.grace"); GraceObject ret; LocalScope surrounding = new LocalScope(); - surrounding.AddLocalDef("parseNodes", - new DictionaryDataObject(GetPatternDict())); + surrounding.AddLocalDef("parseNodes", GetPatternDict()); ctx.Extend(surrounding); using (StreamReader reader = File.OpenText(path)) { diff --git a/GraceLanguage/Runtime/GraceBoolean.cs b/GraceLanguage/Runtime/GraceBoolean.cs index 11191ae..701795f 100644 --- a/GraceLanguage/Runtime/GraceBoolean.cs +++ b/GraceLanguage/Runtime/GraceBoolean.cs @@ -11,6 +11,8 @@ namespace Grace.Runtime /// A Grace boolean object public class GraceBoolean : GraceObject { + private static Dictionary sharedMethods; + /// The true singleton public static GraceBoolean True = new GraceBoolean(true); @@ -24,81 +26,92 @@ public bool Boolean set; } private GraceBoolean(bool val) + : base(createSharedMethods()) { Boolean = val; - AddMethod("prefix!", - new DelegateMethod0(new NativeMethod0(this.Negate))); - AddMethod("not", - new DelegateMethod0(new NativeMethod0(this.Negate))); - AddMethod("hash", new DelegateMethod0(mHash)); - AddMethod("&&(_)", - new DelegateMethod1Ctx(this.AndAnd)); - AddMethod("||(_)", - new DelegateMethod1Ctx(this.OrOr)); - AddMethod("ifTrue(_)", - new DelegateMethod1Ctx( - new NativeMethod1Ctx(this.IfTrue))); - AddMethod("ifFalse(_)", - new DelegateMethod1Ctx( - new NativeMethod1Ctx(this.IfFalse))); - AddMethod("ifTrue(_) ifFalse(_)", - new DelegateMethodReq( - new NativeMethodReq(this.IfTrueIfFalse))); - AddMethod("andAlso(_)", - new DelegateMethod1Ctx( - new NativeMethod1Ctx(this.AndAlso))); - AddMethod("orElse(_)", - new DelegateMethod1Ctx( - new NativeMethod1Ctx(this.OrElse))); - AddMethod("match(_)", new DelegateMethod1Ctx( - new NativeMethod1Ctx(this.Match))); - AddMethod("asString", - new DelegateMethod0(new NativeMethod0(this.AsString))); + } + + private static Dictionary createSharedMethods() + { + if (sharedMethods != null) + return sharedMethods; + sharedMethods = new Dictionary + { + { "prefix!", new DelegateMethodTyped0(Negate) }, + { "not", new DelegateMethodTyped0(Negate) }, + { "hash", new DelegateMethodTyped0(mHash) }, + { "&&(_)", new DelegateMethodTyped1Ctx(AndAnd) }, + { "||(_)", new DelegateMethodTyped1Ctx(OrOr) }, + { "ifTrue(_)", new DelegateMethodTyped1Ctx(IfTrue) }, + { "ifFalse(_)", new DelegateMethodTyped1Ctx(IfFalse) }, + { "ifTrue(_) ifFalse(_)", new DelegateMethodTyped(IfTrueIfFalse) }, + { "andAlso(_)", new DelegateMethodTyped1Ctx(AndAlso) }, + { "orElse(_)", new DelegateMethodTyped1Ctx(OrElse) }, + { "match(_)", new DelegateMethodTyped1Ctx(Match) }, + { "asString", new DelegateMethodTyped0(AsString) }, + }; + return sharedMethods; + } + + /// + /// Apply an extension trait to all future instances of this type. + /// + /// + /// Dictionary of methods to add. + /// + public static void ExtendWith(IDictionary meths) + { + if (sharedMethods == null) + createSharedMethods(); + foreach (var m in meths) + sharedMethods[m.Key] = m.Value; } /// Native method for Grace ! - public GraceObject Negate() + public static GraceObject Negate(GraceBoolean self) { - if (Boolean) + if (self.Boolean) return GraceBoolean.False; return GraceBoolean.True; } - private GraceObject mHash() + private static GraceObject mHash(GraceBoolean self) { - return GraceNumber.Create(Boolean.GetHashCode()); + return GraceNumber.Create(self.Boolean.GetHashCode()); } /// Native method for Grace match /// Current interpreter + /// Receiver of the method /// Target of the match - public GraceObject Match(EvaluationContext ctx, GraceObject target) + public static GraceObject Match(EvaluationContext ctx, GraceBoolean self, GraceObject target) { var b = target as GraceBoolean; - if (b != null && b.Boolean == Boolean) + if (b != null && b.Boolean == self.Boolean) return Matching.SuccessfulMatch(ctx, target); return Matching.FailedMatch(ctx, target); } /// Native method for Grace asString - public GraceObject AsString() + public static GraceObject AsString(GraceBoolean self) { - if (Boolean) + if (self.Boolean) return GraceString.Create("true"); return GraceString.Create("false"); } /// Native method for Grace && /// Current interpreter + /// Receiver of the method /// Argument to the method - public GraceObject AndAnd(EvaluationContext ctx, GraceObject other) + public static GraceObject AndAnd(EvaluationContext ctx, GraceBoolean self, GraceObject other) { GraceBoolean oth = other as GraceBoolean; if (oth != null) - return GraceBoolean.Create(this.Boolean && oth.Boolean); + return GraceBoolean.Create(self.Boolean && oth.Boolean); GraceObjectProxy op = other as GraceObjectProxy; if (op != null) - return GraceBoolean.Create(this.Boolean && (dynamic)op.Object); + return GraceBoolean.Create(self.Boolean && (dynamic)op.Object); ErrorReporting.RaiseError(ctx, "R2001", new Dictionary() { { "method", "&&" }, @@ -113,15 +126,16 @@ public GraceObject AndAnd(EvaluationContext ctx, GraceObject other) /// Native method for Grace || /// Current interpreter + /// Receiver of the method /// Argument to the method - public GraceObject OrOr(EvaluationContext ctx, GraceObject other) + public static GraceObject OrOr(EvaluationContext ctx, GraceBoolean self, GraceObject other) { GraceBoolean oth = other as GraceBoolean; if (oth != null) - return GraceBoolean.Create(this.Boolean || oth.Boolean); + return GraceBoolean.Create(self.Boolean || oth.Boolean); GraceObjectProxy op = other as GraceObjectProxy; if (op != null) - return GraceBoolean.Create(this.Boolean || (dynamic)op.Object); + return GraceBoolean.Create(self.Boolean || (dynamic)op.Object); ErrorReporting.RaiseError(ctx, "R2001", new Dictionary() { { "method", "||" }, @@ -136,8 +150,9 @@ public GraceObject OrOr(EvaluationContext ctx, GraceObject other) /// Native method for Grace ifTrue /// Current interpreter + /// Receiver of the method /// Block to apply if true - public GraceObject IfTrue(EvaluationContext ctx, GraceObject other) + public static GraceObject IfTrue(EvaluationContext ctx, GraceBoolean self, GraceObject other) { var oth = other as GraceBlock; if (oth == null) @@ -150,7 +165,7 @@ public GraceObject IfTrue(EvaluationContext ctx, GraceObject other) }, "ArgumentTypeError: ifTrue requires a block argument" ); - if (Boolean) + if (self.Boolean) { var req = MethodRequest.Nullary("apply"); other.Request(ctx, req); @@ -160,8 +175,9 @@ public GraceObject IfTrue(EvaluationContext ctx, GraceObject other) /// Native method for Grace ifFalse /// Current interpreter + /// Receiver of the method /// Block to apply if false - public GraceObject IfFalse(EvaluationContext ctx, GraceObject other) + public static GraceObject IfFalse(EvaluationContext ctx, GraceBoolean self, GraceObject other) { var oth = other as GraceBlock; if (oth == null) @@ -174,7 +190,7 @@ public GraceObject IfFalse(EvaluationContext ctx, GraceObject other) }, "ArgumentTypeError: ifFalse requires a block argument" ); - if (!Boolean) + if (!self.Boolean) { var req = MethodRequest.Nullary("apply"); other.Request(ctx, req); @@ -184,10 +200,11 @@ public GraceObject IfFalse(EvaluationContext ctx, GraceObject other) /// Native method for Grace ifTrue ifFalse /// Current interpreter + /// Receiver of the method /// Method request that gave rise to this method /// execution - public GraceObject IfTrueIfFalse(EvaluationContext ctx, - MethodRequest req) + public static GraceObject IfTrueIfFalse(EvaluationContext ctx, + MethodRequest req, GraceBoolean self) { MethodHelper.CheckArity(ctx, req, 1, 1); var trueBlock = req[0].Arguments[0]; @@ -213,7 +230,7 @@ public GraceObject IfTrueIfFalse(EvaluationContext ctx, "ArgumentTypeError: ifTrue ifFalse requires two block arguments" ); var apply = MethodRequest.Nullary("apply"); - if (Boolean) + if (self.Boolean) { return trueBlock.Request(ctx, apply); } @@ -222,8 +239,9 @@ public GraceObject IfTrueIfFalse(EvaluationContext ctx, /// Native method for Grace andAlso /// Current interpreter + /// Receiver of the method /// Block to apply if true - public GraceObject AndAlso(EvaluationContext ctx, GraceObject other) + public static GraceObject AndAlso(EvaluationContext ctx, GraceBoolean self, GraceObject other) { var oth = other as GraceBlock; if (oth == null) @@ -236,7 +254,7 @@ public GraceObject AndAlso(EvaluationContext ctx, GraceObject other) }, "ArgumentTypeError: andAlso requires a block argument" ); - if (Boolean) + if (self.Boolean) { var req = MethodRequest.Nullary("apply"); return other.Request(ctx, req); @@ -246,8 +264,9 @@ public GraceObject AndAlso(EvaluationContext ctx, GraceObject other) /// Native method for Grace orElse /// Current interpreter + /// Receiver of the method /// Block to apply if false - public GraceObject OrElse(EvaluationContext ctx, GraceObject other) + public static GraceObject OrElse(EvaluationContext ctx, GraceBoolean self, GraceObject other) { var oth = other as GraceBlock; if (oth == null) @@ -260,7 +279,7 @@ public GraceObject OrElse(EvaluationContext ctx, GraceObject other) }, "ArgumentTypeError: orElse requires a block argument" ); - if (!Boolean) + if (!self.Boolean) { var req = MethodRequest.Nullary("apply"); return other.Request(ctx, req); diff --git a/GraceLanguage/Runtime/GraceObject.cs b/GraceLanguage/Runtime/GraceObject.cs index e54851a..691419b 100644 --- a/GraceLanguage/Runtime/GraceObject.cs +++ b/GraceLanguage/Runtime/GraceObject.cs @@ -163,6 +163,7 @@ private void initialise(bool defaults) AddMethod("asString", null); AddMethod("==(_)", null); AddMethod("!=(_)", null); + AddMethod("hash", null); } } @@ -218,6 +219,15 @@ private static GraceObject mNotEquals(EvaluationContext ctx, return GraceBoolean.Create(!object.ReferenceEquals(self, other)); } + /// Native method supporting Grace hash + /// Current interpreter + /// Receiver + private static GraceObject mHash(EvaluationContext ctx, + GraceObject self) + { + return GraceNumber.Create(RuntimeHelpers.GetHashCode(self)); + } + /// Remove a method from this object /// Method name to remove public virtual void RemoveMethod(string m) @@ -289,6 +299,9 @@ protected virtual Method getLazyMethod(string name) case "!=(_)": m = new DelegateMethodReceiver1Ctx(mNotEquals); return m; + case "hash": + m = new DelegateMethodReceiver0Ctx(mHash); + return m; } return null; } diff --git a/GraceLanguage/Runtime/GraceObjectProxy.cs b/GraceLanguage/Runtime/GraceObjectProxy.cs index d24bd9d..b61b3e4 100644 --- a/GraceLanguage/Runtime/GraceObjectProxy.cs +++ b/GraceLanguage/Runtime/GraceObjectProxy.cs @@ -114,7 +114,12 @@ public override GraceObject Request(EvaluationContext ctx, MethodRequest req) }, "LookupError: Native proxy failed to find method «${method}»" ); - return GraceObjectProxy.Create(meth.Invoke(obj, args)); + try { + return GraceObjectProxy.Create(meth.Invoke(obj, args)); + } catch (TargetInvocationException ex) { + System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex.InnerException).Throw(); + throw null; // Unreachable + } } private static object viewAsNative(Object obj) diff --git a/GraceLanguage/Runtime/GraceType.cs b/GraceLanguage/Runtime/GraceType.cs index 23afbfb..295e666 100644 --- a/GraceLanguage/Runtime/GraceType.cs +++ b/GraceLanguage/Runtime/GraceType.cs @@ -6,6 +6,8 @@ namespace Grace.Runtime /// A Grace type literal public class GraceType : GraceObject { + internal static Dictionary sharedMethods = new Dictionary { }; + private readonly string name; private List methods = new List(); private List requests; @@ -19,6 +21,19 @@ public GraceType(string name) new NativeMethod1Ctx(this.Match))); AddMethod("|(_)", Matching.OrMethod); AddMethod("&(_)", Matching.AndMethod); + AddMethods(GraceType.sharedMethods); + } + + /// + /// Apply an extension trait to all future instances of this type. + /// + /// + /// Dictionary of methods to add. + /// + public static void ExtendWith(IDictionary meths) + { + foreach (var m in meths) + sharedMethods[m.Key] = m.Value; } /// Add a method type entry to this type diff --git a/GraceLanguage/Runtime/Iterables.cs b/GraceLanguage/Runtime/Iterables.cs index e1cdb75..676f300 100644 --- a/GraceLanguage/Runtime/Iterables.cs +++ b/GraceLanguage/Runtime/Iterables.cs @@ -11,6 +11,20 @@ namespace Grace.Runtime /// Encapsulates behaviour relating to iterables public static class Iterables { + internal static Dictionary sharedMethods = new Dictionary { }; + + /// + /// Apply an extension trait to all future instances of this type. + /// + /// + /// Dictionary of methods to add. + /// + public static void ExtendWith(IDictionary meths) + { + foreach (var m in meths) + sharedMethods[m.Key] = m.Value; + } + /// /// Execute a block of native code for each element /// of an iterable. @@ -56,6 +70,7 @@ public Concatenated(GraceObject l, GraceObject r) new DelegateMethod1Ctx( new NativeMethod1Ctx(this.Do))); AddMethod("++(_)", Iterables.ConcatMethod); + AddMethods(sharedMethods); TagName = "ConcatenatedIterables"; } @@ -112,6 +127,7 @@ public GraceVariadicList() AddMethod("with(_) do(_)", new DelegateMethodReq( new NativeMethodReq(this.WithDo))); + AddMethods(Iterables.sharedMethods); TagName = "Lineup"; } diff --git a/GraceLanguage/Runtime/Matching.cs b/GraceLanguage/Runtime/Matching.cs index 0a98afe..1e24737 100644 --- a/GraceLanguage/Runtime/Matching.cs +++ b/GraceLanguage/Runtime/Matching.cs @@ -103,7 +103,7 @@ public static GraceObject AndCombinator(EvaluationContext ctx, GraceObject self, GraceObject other) { var patReq = new MethodRequest(); - patReq.AddPart(new RequestPart("_OrPattern", + patReq.AddPart(new RequestPart("_AndPattern", RequestPart.EmptyList, new List { self, other })); GraceObject patRec = ctx.FindReceiver(patReq); @@ -127,6 +127,7 @@ public NativeTypePattern() AddMethod("match(_)", new DelegateMethod1Ctx(mMatch)); AddMethod("|(_)", Matching.OrMethod); AddMethod("&(_)", Matching.AndMethod); + AddMethods(GraceType.sharedMethods); } /// Native method for Grace match diff --git a/GraceLanguage/modules/platform/kernancompiler.cs b/GraceLanguage/modules/platform/kernancompiler.cs index c69ff57..08c5029 100644 --- a/GraceLanguage/modules/platform/kernancompiler.cs +++ b/GraceLanguage/modules/platform/kernancompiler.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Generic; +using System.Linq; using System.IO; using Grace.Parsing; using Grace.Execution; @@ -12,7 +14,6 @@ namespace KernanCompiler [ModuleEntryPoint] public class ExposedCompiler : GraceObject { - private ParseNodePatternDictObject parseNodes; public static GraceObject Instantiate( EvaluationContext ctx) @@ -22,41 +23,80 @@ public static GraceObject Instantiate( public ExposedCompiler() : base("platform/kernancompiler") { - AddMethod("parse(_)", new DelegateMethod1( - new NativeMethod1(mParse))); - AddMethod("parseFile(_)", new DelegateMethod1( - new NativeMethod1(mParseFile))); - AddMethod("translateFile(_)", new DelegateMethod1( - new NativeMethod1(mTranslateFile))); - AddMethod("parseNodes", new DelegateMethod0( - new NativeMethod0(mParseNodes))); + AddMethod("parse(_)", new DelegateMethod1Ctx((ctx, code) => mParse(ctx, GraceString.Create("source code"), code))); + AddMethod("parse(_,_)", new DelegateMethodReq((ctx, req) => { + MethodHelper.CheckArity(ctx, req, 2); + return mParse(ctx, req[0].Arguments[0], req[0].Arguments[1]); })); + AddMethod("parseFile(_)", new DelegateMethod1(mParseFile)); + AddMethod("readGraceModule(_)", new DelegateMethod1Ctx(mReadGraceModule)); + AddMethod("translateFile(_)", new DelegateMethod1(mTranslateFile)); + AddMethod("parseNodes", new DelegateMethod0(() => ParseNodeMeta.GetPatternDict())); AddMethod("args", new DelegateMethod0( - new NativeMethod0(mArguments))); + () => GraceVariadicList.Of(UnusedArguments.UnusedArgs.Select(GraceString.Create)))); } - private GraceObject mParse(GraceObject code) + private GraceObject mParse(EvaluationContext ctx, GraceObject gmodulename, GraceObject gcode) { - GraceString gs = code.FindNativeParent(); - string s = gs.Value; - var p = new Parser(s); - return new GraceObjectProxy(p.Parse()); + String modulename = gmodulename.FindNativeParent().Value; + String code = gcode.FindNativeParent().Value; + try { + bool sup = ErrorReporting.SuppressAllErrors; + ErrorReporting.SuppressAllErrors = true; // Don't print error messages, as we will forward them to grace + var res = new GraceObjectProxy(new Parser(modulename, code).Parse()); + ErrorReporting.SuppressAllErrors = sup; // Restore old value + return res; + } catch (StaticErrorException exc) { + GraceExceptionPacket.Throw("StaticError", $"{exc.Code}: {exc.Message}; at line {exc.Line}", ctx.GetStackTrace()); + throw null; // unreachable! + } } - private GraceObject mParseFile(GraceObject code) + private GraceObject mParseFile(GraceObject gpath) { - GraceString gs = code.FindNativeParent(); - string path = gs.Value; + String path = gpath.FindNativeParent().Value; using (StreamReader reader = File.OpenText(path)) { - var p= new Parser(reader.ReadToEnd()); - return new GraceObjectProxy(p.Parse()); + return new GraceObjectProxy(new Parser(path, reader.ReadToEnd()).Parse()); + } + } + + private GraceObject mReadGraceModule(EvaluationContext ctx, GraceObject gpath) + { + var itp = (Interpreter)ctx; + String path = gpath.FindNativeParent().Value; + + var name = Path.GetFileName(path); + var bases = itp.GetModulePaths(); + foreach (var p in bases) + { + string filePath; + + filePath = Path.Combine(p, path + ".grace"); + + String mod_contents = itp.TryReadModuleFile(filePath, path); + if (mod_contents != null) + { + return GraceString.Create(mod_contents.Replace(Environment.NewLine, "\u2028")); + } + } + if (itp.FailedImportHook != null) + { + // Optionally, the host program can try to satisfy a module + // and indicate that we should retry the import. + if (itp.FailedImportHook(path, itp)) + { + return mReadGraceModule(itp, gpath); + } } + ErrorReporting.RaiseError(itp, "R2005", + new Dictionary { { "path", path } }, + "LookupError: Could not find module ${path}"); + return null; } - private GraceObject mTranslateFile(GraceObject code) + private GraceObject mTranslateFile(GraceObject gpath) { - GraceString gs = code.FindNativeParent(); - string path = gs.Value; + String path = gpath.FindNativeParent().Value; using (StreamReader reader = File.OpenText(path)) { var p = new Parser(reader.ReadToEnd()); @@ -66,73 +106,5 @@ private GraceObject mTranslateFile(GraceObject code) return eModule; } } - - private GraceObject mArguments() - { - IList unusedArguments = UnusedArguments.UnusedArgs; - IList graceUnusedArguments = new List(); - - foreach (var a in unusedArguments) - graceUnusedArguments.Add(GraceString.Create(a)); - - return GraceVariadicList.Of(graceUnusedArguments); - } - - - private GraceObject mParseNodes() - { - if (parseNodes == null) - parseNodes = new ParseNodePatternDictObject(); - return parseNodes; - } - } - - class NativeTypePattern : GraceObject { - public NativeTypePattern() - { - AddMethod("match(_)", new DelegateMethod1Ctx( - new NativeMethod1Ctx(mMatch))); - AddMethod("|", Matching.OrMethod); - AddMethod("&", Matching.AndMethod); - } - - /// Native method for Grace match - /// Current interpreter - /// Target of the match - private GraceObject mMatch(EvaluationContext ctx, GraceObject target) - { - var gop = target as GraceObjectProxy; - if (gop == null) - return Matching.FailedMatch(ctx, target); - if (gop.Object is T) - return Matching.SuccessfulMatch(ctx, target); - return Matching.FailedMatch(ctx, target); - } - } - - class ParseNodePatternDictObject : GraceObject, - IEnumerable> - { - private Dictionary data = - ParseNodeMeta.GetPatternDict(); - - public override GraceObject Request(EvaluationContext ctx, - MethodRequest req) - { - if (data.ContainsKey(req.Name)) - return data[req.Name]; - return base.Request(ctx, req); - } - - public IEnumerator> GetEnumerator() - { - return data.GetEnumerator(); - } - - System.Collections.IEnumerator - System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } } }