From 7fd15028d4988d87c2e3aa836427f4fbdd874aa7 Mon Sep 17 00:00:00 2001 From: Suzanne Soy Date: Tue, 1 Sep 2020 13:04:57 +0000 Subject: [PATCH] Version submited to the language jam --- AstGenerator.cs | 3 ++- DefaultGrammar.cs | 2 +- Evaluator.cs | 25 ++++++++++++++++++++++--- MixFixGenerator.cs | 1 + Tests/004-foo42.e | 2 +- Tests/005-42foo.e | 2 +- Tests/007-bool.e | 1 + Tests/007-bool.o | 1 + Tests/008-eq2.e | 1 + Tests/008-eq2.o | 1 + main.cs | 5 +++-- 11 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 Tests/007-bool.e create mode 100644 Tests/007-bool.o create mode 100644 Tests/008-eq2.e create mode 100644 Tests/008-eq2.o diff --git a/AstGenerator.cs b/AstGenerator.cs index 8c38c0e..c38387c 100644 --- a/AstGenerator.cs +++ b/AstGenerator.cs @@ -15,7 +15,8 @@ public static class AstGenerator { Variant("Val", Case("int", "Int"), - Case("string", "String")), + Case("string", "String"), + Case("bool", "Bool")), Variant("ParserResult", Case("(MixFix.Annotation, ParserResult)", "Annotated"), diff --git a/DefaultGrammar.cs b/DefaultGrammar.cs index 7edd791..2f68f23 100644 --- a/DefaultGrammar.cs +++ b/DefaultGrammar.cs @@ -13,7 +13,7 @@ public static class DefaultGrammar { .WithOperator("int", LiteralInt, NonAssociative, S.Int) .WithOperator("additive", Unsupported, LeftAssociative, "int|terminal|multiplicative", S.Plus, "int|terminal|multiplicative") .WithOperator("multiplicative", Unsupported, LeftAssociative, "int|terminal", S.Times, "int|terminal") - .WithOperator("terminal", Unsupported, NonAssociative, S.Ident) + .WithOperator("terminal", EnvLookup, NonAssociative, S.Ident) // This is the root set of operators // TODO: this needs aliases .WithOperator("prog", And, LeftAssociative, "equality|terminal", S.And, "equality|terminal") diff --git a/Evaluator.cs b/Evaluator.cs index 8e5647c..a9222bd 100644 --- a/Evaluator.cs +++ b/Evaluator.cs @@ -7,9 +7,13 @@ using static Global; public class Evaluator { public static string EvaluateWrap(Ast.AstNode source) - => Evaluate(source, ImmutableDictionary.Empty).Match( + => Evaluate(source, new Dictionary { + { "true", Ast.Val.Bool(true) }, + { "false", Ast.Val.Bool(false) } + }.ToImmutableDictionary()).Match( Int: i => i.ToString(), - String: s => s); + String: s => s, + Bool: b => b ? "true" : "false"); public static Ast.Val Evaluate(Ast.AstNode source, ImmutableDictionary env) // => Log(source.Str(), () @@ -23,6 +27,16 @@ public class Evaluator { // TODO: check that the last token is indeed Program return Evaluate(o.Item2.ElementAt(1), env); }, + EnvLookup: () => + o.Item2 + .Single() + .ElseThrow( + new RuntimeErrorException("EnvLookup should contain a single lexeme")) + .AsTerminal + .ElseThrow( + new RuntimeErrorException("EnvLookup's contents should be a lexeme")) + .lexeme + .Pipe(x => env[x]), And: () => { if (o.Item2.Count() != 3) { throw new RuntimeErrorException("The And operator should contain three parts"); @@ -30,7 +44,12 @@ public class Evaluator { // TODO: check that the last token is indeed Program var a = Evaluate(o.Item2.ElementAt(0), env); var b = Evaluate(o.Item2.ElementAt(2), env); - return Ast.Val.Int(999); + return + Ast.Val.Bool( + a.AsBool.ElseThrow(new RuntimeErrorException("type error: and requires two bools")) + && + b.AsBool.ElseThrow(new RuntimeErrorException("type error: and requires two bools")) + ); }, LiteralInt: () => o.Item2 diff --git a/MixFixGenerator.cs b/MixFixGenerator.cs index b4243eb..1375f98 100644 --- a/MixFixGenerator.cs +++ b/MixFixGenerator.cs @@ -59,6 +59,7 @@ public static class ParserGenerator { Case("LiteralInt"), Case("LiteralString"), Case("And"), + Case("EnvLookup"), Case("Unsupported")), Variant("Part", diff --git a/Tests/004-foo42.e b/Tests/004-foo42.e index 44ccc5a..bdba533 100644 --- a/Tests/004-foo42.e +++ b/Tests/004-foo42.e @@ -1 +1 @@ -"foo"42 \ No newline at end of file +"foo42" \ No newline at end of file diff --git a/Tests/005-42foo.e b/Tests/005-42foo.e index c18f1e7..a1c1c8c 100644 --- a/Tests/005-42foo.e +++ b/Tests/005-42foo.e @@ -1 +1 @@ -42"foo" \ No newline at end of file +"42foo" \ No newline at end of file diff --git a/Tests/007-bool.e b/Tests/007-bool.e new file mode 100644 index 0000000..5aa6034 --- /dev/null +++ b/Tests/007-bool.e @@ -0,0 +1 @@ +true && false \ No newline at end of file diff --git a/Tests/007-bool.o b/Tests/007-bool.o new file mode 100644 index 0000000..02e4a84 --- /dev/null +++ b/Tests/007-bool.o @@ -0,0 +1 @@ +false \ No newline at end of file diff --git a/Tests/008-eq2.e b/Tests/008-eq2.e new file mode 100644 index 0000000..b9fa03e --- /dev/null +++ b/Tests/008-eq2.e @@ -0,0 +1 @@ +40 + 2 == 40 + 1 + 1 && true \ No newline at end of file diff --git a/Tests/008-eq2.o b/Tests/008-eq2.o new file mode 100644 index 0000000..f32a580 --- /dev/null +++ b/Tests/008-eq2.o @@ -0,0 +1 @@ +true \ No newline at end of file diff --git a/main.cs b/main.cs index 1c3e182..022b61d 100644 --- a/main.cs +++ b/main.cs @@ -90,8 +90,9 @@ public static class MainClass { Console.WriteLine(" Expression ="); Console.WriteLine(" Int"); Console.WriteLine(" | String"); - Console.WriteLine(" | Variable"); - Console.WriteLine(" | Pattern \"->\" Expression"); + Console.WriteLine(" | true"); + Console.WriteLine(" | false"); + Console.WriteLine(" | Expression && Expression"); Console.WriteLine(""); Console.WriteLine("I'll run the tests for you in the meanwhile."); Console.WriteLine("");