Version submited to the language jam
This commit is contained in:
parent
5f11930009
commit
7fd15028d4
|
@ -15,7 +15,8 @@ public static class AstGenerator {
|
||||||
|
|
||||||
Variant("Val",
|
Variant("Val",
|
||||||
Case("int", "Int"),
|
Case("int", "Int"),
|
||||||
Case("string", "String")),
|
Case("string", "String"),
|
||||||
|
Case("bool", "Bool")),
|
||||||
|
|
||||||
Variant("ParserResult",
|
Variant("ParserResult",
|
||||||
Case("(MixFix.Annotation, ParserResult)", "Annotated"),
|
Case("(MixFix.Annotation, ParserResult)", "Annotated"),
|
||||||
|
|
|
@ -13,7 +13,7 @@ public static class DefaultGrammar {
|
||||||
.WithOperator("int", LiteralInt, NonAssociative, S.Int)
|
.WithOperator("int", LiteralInt, NonAssociative, S.Int)
|
||||||
.WithOperator("additive", Unsupported, LeftAssociative, "int|terminal|multiplicative", S.Plus, "int|terminal|multiplicative")
|
.WithOperator("additive", Unsupported, LeftAssociative, "int|terminal|multiplicative", S.Plus, "int|terminal|multiplicative")
|
||||||
.WithOperator("multiplicative", Unsupported, LeftAssociative, "int|terminal", S.Times, "int|terminal")
|
.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
|
// This is the root set of operators
|
||||||
// TODO: this needs aliases
|
// TODO: this needs aliases
|
||||||
.WithOperator("prog", And, LeftAssociative, "equality|terminal", S.And, "equality|terminal")
|
.WithOperator("prog", And, LeftAssociative, "equality|terminal", S.And, "equality|terminal")
|
||||||
|
|
25
Evaluator.cs
25
Evaluator.cs
|
@ -7,9 +7,13 @@ using static Global;
|
||||||
|
|
||||||
public class Evaluator {
|
public class Evaluator {
|
||||||
public static string EvaluateWrap(Ast.AstNode source)
|
public static string EvaluateWrap(Ast.AstNode source)
|
||||||
=> Evaluate(source, ImmutableDictionary<string, Ast.Val>.Empty).Match(
|
=> Evaluate(source, new Dictionary<string, Ast.Val> {
|
||||||
|
{ "true", Ast.Val.Bool(true) },
|
||||||
|
{ "false", Ast.Val.Bool(false) }
|
||||||
|
}.ToImmutableDictionary()).Match(
|
||||||
Int: i => i.ToString(),
|
Int: i => i.ToString(),
|
||||||
String: s => s);
|
String: s => s,
|
||||||
|
Bool: b => b ? "true" : "false");
|
||||||
|
|
||||||
public static Ast.Val Evaluate(Ast.AstNode source, ImmutableDictionary<string, Ast.Val> env)
|
public static Ast.Val Evaluate(Ast.AstNode source, ImmutableDictionary<string, Ast.Val> env)
|
||||||
// => Log(source.Str(), ()
|
// => Log(source.Str(), ()
|
||||||
|
@ -23,6 +27,16 @@ public class Evaluator {
|
||||||
// TODO: check that the last token is indeed Program
|
// TODO: check that the last token is indeed Program
|
||||||
return Evaluate(o.Item2.ElementAt(1), env);
|
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: () => {
|
And: () => {
|
||||||
if (o.Item2.Count() != 3) {
|
if (o.Item2.Count() != 3) {
|
||||||
throw new RuntimeErrorException("The And operator should contain three parts");
|
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
|
// TODO: check that the last token is indeed Program
|
||||||
var a = Evaluate(o.Item2.ElementAt(0), env);
|
var a = Evaluate(o.Item2.ElementAt(0), env);
|
||||||
var b = Evaluate(o.Item2.ElementAt(2), 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: () =>
|
LiteralInt: () =>
|
||||||
o.Item2
|
o.Item2
|
||||||
|
|
|
@ -59,6 +59,7 @@ public static class ParserGenerator {
|
||||||
Case("LiteralInt"),
|
Case("LiteralInt"),
|
||||||
Case("LiteralString"),
|
Case("LiteralString"),
|
||||||
Case("And"),
|
Case("And"),
|
||||||
|
Case("EnvLookup"),
|
||||||
Case("Unsupported")),
|
Case("Unsupported")),
|
||||||
|
|
||||||
Variant("Part",
|
Variant("Part",
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
"foo"42
|
"foo42"
|
|
@ -1 +1 @@
|
||||||
42"foo"
|
"42foo"
|
1
Tests/007-bool.e
Normal file
1
Tests/007-bool.e
Normal file
|
@ -0,0 +1 @@
|
||||||
|
true && false
|
1
Tests/007-bool.o
Normal file
1
Tests/007-bool.o
Normal file
|
@ -0,0 +1 @@
|
||||||
|
false
|
1
Tests/008-eq2.e
Normal file
1
Tests/008-eq2.e
Normal file
|
@ -0,0 +1 @@
|
||||||
|
40 + 2 == 40 + 1 + 1 && true
|
1
Tests/008-eq2.o
Normal file
1
Tests/008-eq2.o
Normal file
|
@ -0,0 +1 @@
|
||||||
|
true
|
5
main.cs
5
main.cs
|
@ -90,8 +90,9 @@ public static class MainClass {
|
||||||
Console.WriteLine(" Expression =");
|
Console.WriteLine(" Expression =");
|
||||||
Console.WriteLine(" Int");
|
Console.WriteLine(" Int");
|
||||||
Console.WriteLine(" | String");
|
Console.WriteLine(" | String");
|
||||||
Console.WriteLine(" | Variable");
|
Console.WriteLine(" | true");
|
||||||
Console.WriteLine(" | Pattern \"->\" Expression");
|
Console.WriteLine(" | false");
|
||||||
|
Console.WriteLine(" | Expression && Expression");
|
||||||
Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
Console.WriteLine("I'll run the tests for you in the meanwhile.");
|
Console.WriteLine("I'll run the tests for you in the meanwhile.");
|
||||||
Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user