WIP
This commit is contained in:
parent
de12594067
commit
5f11930009
|
@ -2,7 +2,7 @@ namespace Compilers {
|
||||||
public class JS {
|
public class JS {
|
||||||
public static string Compile(Ast.AstNode source) {
|
public static string Compile(Ast.AstNode source) {
|
||||||
return "process.stdout.write(String("
|
return "process.stdout.write(String("
|
||||||
+ "\"no JS for now\""
|
+ "\"NO JavaScript COMPILATION FOR NOW\""
|
||||||
/* + source.Match(
|
/* + source.Match(
|
||||||
Int: i => i.ToString(),
|
Int: i => i.ToString(),
|
||||||
String: s => $"'{s.ToString()}'"
|
String: s => $"'{s.ToString()}'"
|
||||||
|
|
|
@ -16,7 +16,7 @@ public static class DefaultGrammar {
|
||||||
.WithOperator("terminal", Unsupported, NonAssociative, S.Ident)
|
.WithOperator("terminal", Unsupported, 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", Unsupported, LeftAssociative, "equality|terminal", S.And, "equality|terminal")
|
.WithOperator("prog", And, LeftAssociative, "equality|terminal", S.And, "equality|terminal")
|
||||||
.WithOperator("prog", LiteralInt, NonAssociative, S.Int)
|
.WithOperator("prog", LiteralInt, NonAssociative, S.Int)
|
||||||
.WithOperator("prog", LiteralString, NonAssociative, S.StringOpen, S.String, S.StringClose)
|
.WithOperator("prog", LiteralString, NonAssociative, S.StringOpen, S.String, S.StringClose)
|
||||||
.WithOperator("program", Program, NonAssociative, S.StartOfInput, "prog", S.EndOfInput)
|
.WithOperator("program", Program, NonAssociative, S.StartOfInput, "prog", S.EndOfInput)
|
||||||
|
|
28
Evaluator.cs
28
Evaluator.cs
|
@ -1,10 +1,17 @@
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Immutable;
|
using Immutable;
|
||||||
using static Global;
|
using static Global;
|
||||||
|
|
||||||
public class Evaluator {
|
public class Evaluator {
|
||||||
public static string Evaluate(Ast.AstNode source)
|
public static string EvaluateWrap(Ast.AstNode source)
|
||||||
|
=> Evaluate(source, ImmutableDictionary<string, Ast.Val>.Empty).Match(
|
||||||
|
Int: i => i.ToString(),
|
||||||
|
String: s => s);
|
||||||
|
|
||||||
|
public static Ast.Val Evaluate(Ast.AstNode source, ImmutableDictionary<string, Ast.Val> env)
|
||||||
// => Log(source.Str(), ()
|
// => Log(source.Str(), ()
|
||||||
=> source.Match(
|
=> source.Match(
|
||||||
Operator: o => o.Item1.semantics.Match(
|
Operator: o => o.Item1.semantics.Match(
|
||||||
|
@ -14,7 +21,16 @@ public class Evaluator {
|
||||||
throw new RuntimeErrorException("The Program wrapper should contain two parts: StartOfInput, prog and EndOfInput");
|
throw new RuntimeErrorException("The Program wrapper should contain two parts: StartOfInput, prog and EndOfInput");
|
||||||
}
|
}
|
||||||
// TODO: check that the last token is indeed Program
|
// TODO: check that the last token is indeed Program
|
||||||
return Evaluate(o.Item2.ElementAt(1));
|
return Evaluate(o.Item2.ElementAt(1), env);
|
||||||
|
},
|
||||||
|
And: () => {
|
||||||
|
if (o.Item2.Count() != 3) {
|
||||||
|
throw new RuntimeErrorException("The And operator should contain three parts");
|
||||||
|
}
|
||||||
|
// 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);
|
||||||
},
|
},
|
||||||
LiteralInt: () =>
|
LiteralInt: () =>
|
||||||
o.Item2
|
o.Item2
|
||||||
|
@ -24,7 +40,8 @@ public class Evaluator {
|
||||||
.AsTerminal
|
.AsTerminal
|
||||||
.ElseThrow(
|
.ElseThrow(
|
||||||
new RuntimeErrorException("LiteralInt's contents should be a lexeme"))
|
new RuntimeErrorException("LiteralInt's contents should be a lexeme"))
|
||||||
.lexeme,
|
.lexeme
|
||||||
|
.Pipe(x => Ast.Val.Int(Int32.Parse(x))),
|
||||||
LiteralString: () => {
|
LiteralString: () => {
|
||||||
if (o.Item2.Count() != 3) {
|
if (o.Item2.Count() != 3) {
|
||||||
throw new RuntimeErrorException("LiteralString should contain three lexemes: OpenString, String and CloseString");
|
throw new RuntimeErrorException("LiteralString should contain three lexemes: OpenString, String and CloseString");
|
||||||
|
@ -33,10 +50,11 @@ public class Evaluator {
|
||||||
return o.Item2.ElementAt(1)
|
return o.Item2.ElementAt(1)
|
||||||
.AsTerminal.ElseThrow(
|
.AsTerminal.ElseThrow(
|
||||||
new RuntimeErrorException("LiteralInt's contents should be a lexeme"))
|
new RuntimeErrorException("LiteralInt's contents should be a lexeme"))
|
||||||
.lexeme;
|
.lexeme
|
||||||
|
.Pipe(x => Ast.Val.String(x));
|
||||||
},
|
},
|
||||||
Unsupported: () => throw new RuntimeErrorException($"Unsupported opeartor {o}, sorry.")),
|
Unsupported: () => throw new RuntimeErrorException($"Unsupported opeartor {o}, sorry.")),
|
||||||
Terminal: t => t.lexeme/*TODO*/);
|
Terminal: t => Ast.Val.String(t.lexeme)/*TODO*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: for typeclass resolution, ask that functions have their parameters and return types annotated. This annotation is added to the values at run-time, which allows to dispatch based on the annotation rather than on the actual value.
|
// Note: for typeclass resolution, ask that functions have their parameters and return types annotated. This annotation is added to the values at run-time, which allows to dispatch based on the annotation rather than on the actual value.
|
|
@ -58,6 +58,7 @@ public static class ParserGenerator {
|
||||||
Case("Program"),
|
Case("Program"),
|
||||||
Case("LiteralInt"),
|
Case("LiteralInt"),
|
||||||
Case("LiteralString"),
|
Case("LiteralString"),
|
||||||
|
Case("And"),
|
||||||
Case("Unsupported")),
|
Case("Unsupported")),
|
||||||
|
|
||||||
Variant("Part",
|
Variant("Part",
|
||||||
|
|
8
main.cs
8
main.cs
|
@ -58,8 +58,8 @@ public static class MainClass {
|
||||||
// first-class functions by using repeated .Add()
|
// first-class functions by using repeated .Add()
|
||||||
// See https://repl.it/@suzannesoy/WarlikeWorstTraining#main.cs
|
// See https://repl.it/@suzannesoy/WarlikeWorstTraining#main.cs
|
||||||
var compilers = ImmutableList<Tuple<string, Compiler, Exe>>.Empty
|
var compilers = ImmutableList<Tuple<string, Compiler, Exe>>.Empty
|
||||||
.Add(" js ", Compilers.JS.Compile, Exe("node"))
|
.Add(" js ", Compilers.JS.Compile, Exe("node"))
|
||||||
.Add("eval", Evaluator.Evaluate, Exe("cat"));
|
.Add("eval", Evaluator.EvaluateWrap, Exe("cat"));
|
||||||
|
|
||||||
var total = 0;
|
var total = 0;
|
||||||
var passed = 0;
|
var passed = 0;
|
||||||
|
@ -99,8 +99,8 @@ public static class MainClass {
|
||||||
} else {
|
} else {
|
||||||
var source = args[0].File();
|
var source = args[0].File();
|
||||||
var destPrefix = source.DropExtension();
|
var destPrefix = source.DropExtension();
|
||||||
CompileToFile(Compilers.JS.Compile, source, destPrefix.Combine(Ext(".js")));
|
CompileToFile(Compilers.JS.Compile, source, destPrefix.Combine(Ext(".js")));
|
||||||
CompileToFile(Evaluator.Evaluate, source, destPrefix.Combine(Ext(".txt")));
|
CompileToFile(Evaluator.EvaluateWrap, source, destPrefix.Combine(Ext(".txt")));
|
||||||
Console.Write(destPrefix.Combine(Ext(".txt")).Read());
|
Console.Write(destPrefix.Combine(Ext(".txt")).Read());
|
||||||
}
|
}
|
||||||
} catch (UserErrorException e) {
|
} catch (UserErrorException e) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user