Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 41 additions & 9 deletions GraceLanguage/Execution/Interpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

}

/// <summary>
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -402,12 +432,14 @@ public GraceObject LoadModule(string path)
return null;
}

/// <summary>Load a module file if it exists</summary>
private GraceObject tryLoadModuleFile(string filePath,
/// <summary>Read a module file if it exists</summary>
/// <param name="filePath">Filesystem path to the module</param>
/// <param name="importPath"> Module name to treat this code as belonging to. </param>
public String TryReadModuleFile(string filePath,
string importPath)
{
return (File.Exists(filePath))
? loadModuleFile(filePath, importPath)
? readModuleFile(filePath, importPath)
: null;
}

Expand All @@ -429,13 +461,13 @@ private GraceObject tryLoadResource(string filePath, string importPath)
: null;
}

/// <summary>Load a module file</summary>
private GraceObject loadModuleFile(string filePath, string importPath)
/// <summary>Read a module file</summary>
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();
}
}

Expand Down Expand Up @@ -670,7 +702,7 @@ public static GraceObject BaseTryCatchFinally(EvaluationContext ctx,
/// <inheritdoc />
public int NestRequest(string module, int line, string name)
{
if (callStackMethod.Count > 511) {
if (callStackMethod.Count > 1023) {
ErrorReporting.RaiseError(this, "R2024",
new Dictionary<string, string>(),
"RecursionError: maximum call stack size exceeded."
Expand Down
11 changes: 5 additions & 6 deletions GraceLanguage/Parsing/ParseNodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1953,15 +1953,15 @@ public override T Visit<T>(ParseNodeVisitor<T> visitor)
/// </summary>
public static class ParseNodeMeta
{
private static Dictionary<string, GraceObject> parseNodes;
private static DictionaryDataObject parseNodes;

/// <summary>
/// Get dictionary of parse node names to patterns.
/// </summary>
public static Dictionary<string, GraceObject> GetPatternDict()
public static GraceObject GetPatternDict()
{
if (parseNodes == null)
parseNodes = new Dictionary<string, GraceObject> {
parseNodes = new DictionaryDataObject(new Dictionary<string, GraceObject> {
{ "Object", new NativeTypePattern<ObjectParseNode>() },
{ "MethodDeclaration",
new NativeTypePattern<MethodDeclarationParseNode>() },
Expand Down Expand Up @@ -2021,7 +2021,7 @@ public static Dictionary<string, GraceObject> GetPatternDict()
new NativeTypePattern<ParenthesisedParseNode>() },
{ "Comment", new NativeTypePattern<CommentParseNode>() },

};
});
return parseNodes;
}

Expand All @@ -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))
{
Expand Down
125 changes: 72 additions & 53 deletions GraceLanguage/Runtime/GraceBoolean.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace Grace.Runtime
/// <summary>A Grace boolean object</summary>
public class GraceBoolean : GraceObject
{
private static Dictionary<string, Method> sharedMethods;

/// <summary>The true singleton</summary>
public static GraceBoolean True = new GraceBoolean(true);

Expand All @@ -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<string, Method> createSharedMethods()
{
if (sharedMethods != null)
return sharedMethods;
sharedMethods = new Dictionary<string, Method>
{
{ "prefix!", new DelegateMethodTyped0<GraceBoolean>(Negate) },
{ "not", new DelegateMethodTyped0<GraceBoolean>(Negate) },
{ "hash", new DelegateMethodTyped0<GraceBoolean>(mHash) },
{ "&&(_)", new DelegateMethodTyped1Ctx<GraceBoolean>(AndAnd) },
{ "||(_)", new DelegateMethodTyped1Ctx<GraceBoolean>(OrOr) },
{ "ifTrue(_)", new DelegateMethodTyped1Ctx<GraceBoolean>(IfTrue) },
{ "ifFalse(_)", new DelegateMethodTyped1Ctx<GraceBoolean>(IfFalse) },
{ "ifTrue(_) ifFalse(_)", new DelegateMethodTyped<GraceBoolean>(IfTrueIfFalse) },
{ "andAlso(_)", new DelegateMethodTyped1Ctx<GraceBoolean>(AndAlso) },
{ "orElse(_)", new DelegateMethodTyped1Ctx<GraceBoolean>(OrElse) },
{ "match(_)", new DelegateMethodTyped1Ctx<GraceBoolean>(Match) },
{ "asString", new DelegateMethodTyped0<GraceBoolean>(AsString) },
};
return sharedMethods;
}

/// <summary>
/// Apply an extension trait to all future instances of this type.
/// </summary>
/// <param name="meths">
/// Dictionary of methods to add.
/// </param>
public static void ExtendWith(IDictionary<string, Method> meths)
{
if (sharedMethods == null)
createSharedMethods();
foreach (var m in meths)
sharedMethods[m.Key] = m.Value;
}

/// <summary>Native method for Grace !</summary>
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());
}

/// <summary>Native method for Grace match</summary>
/// <param name="ctx">Current interpreter</param>
/// <param name="self">Receiver of the method</param>
/// <param name="target">Target of the match</param>
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);
}

/// <summary>Native method for Grace asString</summary>
public GraceObject AsString()
public static GraceObject AsString(GraceBoolean self)
{
if (Boolean)
if (self.Boolean)
return GraceString.Create("true");
return GraceString.Create("false");
}

/// <summary>Native method for Grace &amp;&amp;</summary>
/// <param name="ctx">Current interpreter</param>
/// <param name="self">Receiver of the method</param>
/// <param name="other">Argument to the method</param>
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<string, string>() {
{ "method", "&&" },
Expand All @@ -113,15 +126,16 @@ public GraceObject AndAnd(EvaluationContext ctx, GraceObject other)

/// <summary>Native method for Grace ||</summary>
/// <param name="ctx">Current interpreter</param>
/// <param name="self">Receiver of the method</param>
/// <param name="other">Argument to the method</param>
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<string, string>() {
{ "method", "||" },
Expand All @@ -136,8 +150,9 @@ public GraceObject OrOr(EvaluationContext ctx, GraceObject other)

/// <summary>Native method for Grace ifTrue</summary>
/// <param name="ctx">Current interpreter</param>
/// <param name="self">Receiver of the method</param>
/// <param name="other">Block to apply if true</param>
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)
Expand All @@ -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);
Expand All @@ -160,8 +175,9 @@ public GraceObject IfTrue(EvaluationContext ctx, GraceObject other)

/// <summary>Native method for Grace ifFalse</summary>
/// <param name="ctx">Current interpreter</param>
/// <param name="self">Receiver of the method</param>
/// <param name="other">Block to apply if false</param>
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)
Expand All @@ -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);
Expand All @@ -184,10 +200,11 @@ public GraceObject IfFalse(EvaluationContext ctx, GraceObject other)

/// <summary>Native method for Grace ifTrue ifFalse</summary>
/// <param name="ctx">Current interpreter</param>
/// <param name="self">Receiver of the method</param>
/// <param name="req">Method request that gave rise to this method
/// execution</param>
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];
Expand All @@ -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);
}
Expand All @@ -222,8 +239,9 @@ public GraceObject IfTrueIfFalse(EvaluationContext ctx,

/// <summary>Native method for Grace andAlso</summary>
/// <param name="ctx">Current interpreter</param>
/// <param name="self">Receiver of the method</param>
/// <param name="other">Block to apply if true</param>
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)
Expand All @@ -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);
Expand All @@ -246,8 +264,9 @@ public GraceObject AndAlso(EvaluationContext ctx, GraceObject other)

/// <summary>Native method for Grace orElse</summary>
/// <param name="ctx">Current interpreter</param>
/// <param name="self">Receiver of the method</param>
/// <param name="other">Block to apply if false</param>
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)
Expand All @@ -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);
Expand Down
Loading