static void FormatTest() { var sources = Shovel.Api.MakeSources("test.sho", @" var product = hash('name', 'paperweight', 'price', 20) format('The {0} is {1:C2}.', product.name, product.price) "); try { //var bytecode = Shovel.Api.GetBytecode (sources); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); Console.WriteLine(Shovel.Api.TestRunVm(sources)); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); foreach (var pt in parser.ParseTrees) { //Console.WriteLine(pt); } } catch (Shovel.Exceptions.ShovelException shex) { Console.WriteLine(shex.Message); } }
internal static List <Instruction> GetRawBytecode(List <SourceFile> sources) { // Tokenize files. var tokenizedFiles = new List <List <Token> >(); foreach (var sourceFile in sources) { var tokenizer = new Shovel.Compiler.Tokenizer(sourceFile); tokenizedFiles.Add(tokenizer.Tokens); } // Parse files. var parseForests = new List <List <ParseTree> >(); foreach (var tokenizedFile in tokenizedFiles) { var parser = new Shovel.Compiler.Parser(tokenizedFile, sources); parseForests.Add(parser.ParseTrees); } // Flatten the forests of parse trees into one for code generation. var bigParseForest = new List <ParseTree>(); foreach (var parseTrees in parseForests) { bigParseForest.AddRange(parseTrees); } // Generate the code. var codeGenerator = new Shovel.Compiler.CodeGenerator(bigParseForest, sources); return(codeGenerator.Bytecode); }
static void StringInterpolationTest() { var sources = Shovel.Api.MakeSources("test.sho", @" var product = hash('name', 'paperweight', 'price', 19.90) var names = array('John', 'Smith') '${names' "); try { //var bytecode = Shovel.Api.GetBytecode (sources); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); Console.WriteLine(Shovel.Api.TestRunVm(sources)); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); foreach (var pt in parser.ParseTrees) { //Console.WriteLine(pt); } } catch (Shovel.Exceptions.ShovelException shex) { Console.WriteLine(shex.Message); } }
static void CurryTest() { var sources = Shovel.Api.MakeSources("test.sho", @" var curry = fn (f, ...args) fn ...extras apply(f, args + extras) var readableCurry = fn (f, ...args) { fn (...extras) { apply(f, args + extras) } } var add = fn (x, y) x + y var add3 = curry(add, 3) var add31 = readableCurry(add, 3) add3(4) + add31(3) "); try { //var bytecode = Shovel.Api.GetBytecode (sources); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); Console.WriteLine(Shovel.Api.TestRunVm(sources)); Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); foreach (var pt in parser.ParseTrees) { //Console.WriteLine(pt); } } catch (Shovel.Exceptions.ShovelException shex) { Console.WriteLine(shex.Message); } }
static void PostfixTest() { var sources = Shovel.Api.MakeSources("test.sho", @" var f = fn (n, x) n + x var g = fn (x, n) n * x var x = 10 //var z = x -> (fn (x) x + $) x -> (3 + $) -> f(3, $) -> g($, 2) "); try { //var bytecode = Shovel.Api.GetBytecode (sources); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); Console.WriteLine(Shovel.Api.TestRunVm(sources)); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); foreach (var pt in parser.ParseTrees) { //Console.WriteLine(pt); } } catch (Shovel.Exceptions.ShovelException shex) { Console.WriteLine(shex.Message); } }
static void CollectTestTails() { var sources = Shovel.Api.MakeSources("test.sho", @" var fun1 = fn (x, ...rest) { push(rest, x) rest } var fun2 = fn (...rest1) fun1(rest1[0] + rest1[1], 1, 2) stringRepresentation(fun2(1, 2)) "); try { //var bytecode = Shovel.Api.GetBytecode (sources); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); Console.WriteLine(Shovel.Api.TestRunVm(sources)); Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); foreach (var pt in parser.ParseTrees) { //Console.WriteLine(pt); } } catch (Shovel.Exceptions.ShovelException shex) { Console.WriteLine(shex.Message); } }
static void IndirectArrayTest() { var sources = Shovel.Api.MakeSources("test.sho", @" var x = array(1, 2, 3) var getter = fn (obj, index) index * index var y = hash() var setter = fn (obj, index, value) y[string(index)] = value setHandlers(x, getter, setter) //length(x) //x[-1] = 'm' //stringRepresentation(x) x[11] = 'yo' stringRepresentation(x) + ' ' + stringRepresentation(y) "); try { //var bytecode = Shovel.Api.GetBytecode (sources); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); Console.WriteLine(Shovel.Api.TestRunVm(sources)); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); foreach (var pt in parser.ParseTrees) { //Console.WriteLine(pt); } } catch (Shovel.Exceptions.ShovelException shex) { Console.WriteLine(shex.Message); } }
static void MultilineComments() { var sources = Shovel.Api.MakeSources("test.sho", @" /* comments aaa */ var fun = fn (x, y, z) x + y + z fun(/* x */ 1, /* y */ 2, /* z */ 3) "); try { //var bytecode = Shovel.Api.GetBytecode (sources); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); Console.WriteLine(Shovel.Api.TestRunVm(sources)); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); foreach (var pt in parser.ParseTrees) { //Console.WriteLine(pt); } } catch (Shovel.Exceptions.ShovelException shex) { Console.WriteLine(shex.Message); } }
static void ApplyPrimitiveTest() { var sources = Shovel.Api.MakeSources("test.sho", @" var h = apply(hash, array('a', 1, 'b', 2, 'c', array(1, 2))) stringRepresentation(h) //var a = apply(array, array(1, 2, 3)) //stringRepresentation(a) "); try { //var bytecode = Shovel.Api.GetBytecode (sources); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); Console.WriteLine(Shovel.Api.TestRunVm(sources)); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); foreach (var pt in parser.ParseTrees) { //Console.WriteLine(pt); } } catch (Shovel.Exceptions.ShovelException shex) { Console.WriteLine(shex.Message); } }
static void IndirectHashTest() { var sources = Shovel.Api.MakeSources("test.sho", @" var x = hash('a', 1) var getter = fn (obj, propertyName) propertyName + propertyName var y = hash() var setter = fn (obj, propertyName, value) y[propertyName] = value setHandlers(x, getter, setter) var key = 'whatever' //x['whatever'] = 10 x[key] = 10 //x[key] //x.whatever = 10 //x.a = 2 stringRepresentation(x) + ' ' + stringRepresentation(y) "); try { //var bytecode = Shovel.Api.GetBytecode (sources); Console.WriteLine(Shovel.Api.TestRunVm(sources)); Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); foreach (var pt in parser.ParseTrees) { //Console.WriteLine(pt); } } catch (Shovel.Exceptions.ShovelException shex) { Console.WriteLine(shex.Message); } }
static void ApplyTestTails() { var sources = Shovel.Api.MakeSources("test.sho", @" var fun1 = fn (x) x * x var fun2 = fn (x, y) fun1(x + y) fun1(apply(fun2, array(1, 2))) "); try { //var bytecode = Shovel.Api.GetBytecode (sources); //Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); Console.WriteLine(Shovel.Api.TestRunVm(sources)); Console.WriteLine(Shovel.Api.PrintRawBytecode(sources, true)); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); foreach (var pt in parser.ParseTrees) { //Console.WriteLine(pt); } } catch (Shovel.Exceptions.ShovelException shex) { Console.WriteLine(shex.Message); } }
static void ParserErrorMessageHelper(string source, Action <ShovelException> exceptionTest) { var sources = Shovel.Api.MakeSources("test.sho", source); var tokenizer = new Shovel.Compiler.Tokenizer(sources [0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); Utils.ExpectException <ShovelException> (() => { foreach (var pt in parser.ParseTrees) { Console.WriteLine(pt); } }, exceptionTest); }
public void CollectArgumentNotLast() { var source = @" var f = fn (...x, y) x + y "; var sources = Shovel.Api.MakeSources("test.sho", source); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); Utils.ExpectException<ShovelException>(() => { var x = parser.ParseTrees; }, (ex) => { Assert.IsNotNull(ex); Assert.AreEqual(@"Collect arguments (e.g. ""...rest"") allowed only at the end of the argument list. file 'test.sho' line 2: var f = fn (...x, y) x + y file 'test.sho' line 2: ^".TrimCarriageReturn(), ex.Message.TrimCarriageReturn()); Assert.AreEqual("test.sho", ex.FileName); }); }
public void CollectArgumentMultiple() { var source = @" var f = fn (...x, ...y) x + y "; var sources = Shovel.Api.MakeSources("test.sho", source); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); Utils.ExpectException <ShovelException>(() => { var x = parser.ParseTrees; }, (ex) => { Assert.IsNotNull(ex); Assert.AreEqual(@"Only one collect argument (e.g. ""...rest"") allowed. file 'test.sho' line 2: var f = fn (...x, ...y) x + y file 'test.sho' line 2: ^".TrimCarriageReturn(), ex.Message.TrimCarriageReturn()); Assert.AreEqual("test.sho", ex.FileName); }); }
public void WeaveAtMostOneReplacement() { var source = @" var f = fn (x, y) x + y 3 -> f($, $) "; var sources = Shovel.Api.MakeSources("test.sho", source); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); Utils.ExpectException <ShovelException>(() => { var x = parser.ParseTrees; }, (ex) => { Assert.IsNotNull(ex); Assert.AreEqual(@"More than one replacement in postfix call (->, $). file 'test.sho' line 3: 3 -> f($, $) file 'test.sho' line 3: ^".TrimCarriageReturn(), ex.Message.TrimCarriageReturn()); Assert.AreEqual("test.sho", ex.FileName); }); }
public void ParseResult() { var source = @" var fact = fn n if n == 0 1 else n * fact(n - 1) "; var sources = Shovel.Api.MakeSources("test.sho", source); var tokenizer = new Shovel.Compiler.Tokenizer(sources [0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); var sb = new StringBuilder(); foreach (var pt in parser.ParseTrees) { sb.Append(pt.ToString()); } Assert.AreEqual(@"FileName (0 -- 0) 'test.sho' Var (1 -- 48) Name (5 -- 8) 'fact' Fn (12 -- 48) List (15 -- 15) Name (15 -- 15) 'n' If (17 -- 48) Call (20 -- 25) Prim0 (22 -- 23) '==' Name (20 -- 20) 'n' Number (25 -- 25) '0' Number (27 -- 27) '1' Call (34 -- 48) Prim0 (36 -- 36) '*' Name (34 -- 34) 'n' Call (38 -- 48) Name (38 -- 41) 'fact' Call (43 -- 47) Prim0 (45 -- 45) '-' Name (43 -- 43) 'n' Number (47 -- 47) '1' ", sb.ToString()); }
static void ParserErrorMessageHelper(string source, Action<ShovelException> exceptionTest) { var sources = Shovel.Api.MakeSources ("test.sho", source); var tokenizer = new Shovel.Compiler.Tokenizer (sources [0]); var parser = new Shovel.Compiler.Parser (tokenizer.Tokens, sources); Utils.ExpectException<ShovelException> (() => { foreach (var pt in parser.ParseTrees) { Console.WriteLine (pt); } }, exceptionTest); }
public void WeaveAtMostOneReplacement() { var source = @" var f = fn (x, y) x + y 3 -> f($, $) "; var sources = Shovel.Api.MakeSources("test.sho", source); var tokenizer = new Shovel.Compiler.Tokenizer(sources[0]); var parser = new Shovel.Compiler.Parser(tokenizer.Tokens, sources); Utils.ExpectException<ShovelException>(() => { var x = parser.ParseTrees; }, (ex) => { Assert.IsNotNull(ex); Assert.AreEqual(@"More than one replacement in postfix call (->, $). file 'test.sho' line 3: 3 -> f($, $) file 'test.sho' line 3: ^".TrimCarriageReturn(), ex.Message.TrimCarriageReturn()); Assert.AreEqual("test.sho", ex.FileName); }); }
internal static List<Instruction> GetRawBytecode(List<SourceFile> sources) { // Tokenize files. var tokenizedFiles = new List<List<Token>>(); foreach (var sourceFile in sources) { var tokenizer = new Shovel.Compiler.Tokenizer(sourceFile); tokenizedFiles.Add(tokenizer.Tokens); } // Parse files. var parseForests = new List<List<ParseTree>>(); foreach (var tokenizedFile in tokenizedFiles) { var parser = new Shovel.Compiler.Parser(tokenizedFile, sources); parseForests.Add(parser.ParseTrees); } // Flatten the forests of parse trees into one for code generation. var bigParseForest = new List<ParseTree>(); foreach (var parseTrees in parseForests) { bigParseForest.AddRange(parseTrees); } // Generate the code. var codeGenerator = new Shovel.Compiler.CodeGenerator(bigParseForest, sources); return codeGenerator.Bytecode; }
public void ParseResult() { var source = @" var fact = fn n if n == 0 1 else n * fact(n - 1) "; var sources = Shovel.Api.MakeSources ("test.sho", source); var tokenizer = new Shovel.Compiler.Tokenizer (sources [0]); var parser = new Shovel.Compiler.Parser (tokenizer.Tokens, sources); var sb = new StringBuilder(); foreach (var pt in parser.ParseTrees) { sb.Append (pt.ToString()); } Assert.AreEqual (@"FileName (0 -- 0) 'test.sho' Var (1 -- 48) Name (5 -- 8) 'fact' Fn (12 -- 48) List (15 -- 15) Name (15 -- 15) 'n' If (17 -- 48) Call (20 -- 25) Prim0 (22 -- 23) '==' Name (20 -- 20) 'n' Number (25 -- 25) '0' Number (27 -- 27) '1' Call (34 -- 48) Prim0 (36 -- 36) '*' Name (34 -- 34) 'n' Call (38 -- 48) Name (38 -- 41) 'fact' Call (43 -- 47) Prim0 (45 -- 45) '-' Name (43 -- 43) 'n' Number (47 -- 47) '1' ", sb.ToString()); }