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();
- }
}
}