From 12232668d931b0f3593807d2096a2c2f26844b0b Mon Sep 17 00:00:00 2001 From: Martin Dobrev Date: Sun, 18 Nov 2018 20:32:58 +0200 Subject: Code generation improvements (#56) * Implement code generation for some unary expressions Implement debug code augmentation. Now part of expresions have source location. Extend Tokens with Column information. Refactor byte code generation. Add options for byte code generator. * Fix linux build * Little refactoring in byte code generation * Fix couple bugs in byte code generation and add some tests. * Fix some linux warnings. --- JSImpl/test/CodeGenerationTests.cpp | 181 ++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 JSImpl/test/CodeGenerationTests.cpp (limited to 'JSImpl/test/CodeGenerationTests.cpp') diff --git a/JSImpl/test/CodeGenerationTests.cpp b/JSImpl/test/CodeGenerationTests.cpp new file mode 100644 index 0000000..d341562 --- /dev/null +++ b/JSImpl/test/CodeGenerationTests.cpp @@ -0,0 +1,181 @@ +#include +#include +#include +#include "src/ByteCodeGenerator.h" + +#include + +#include + +TEST(CodeGen, Empty) +{ + IPLVector tokens; + IPLString source = ""; + Tokenize(source.c_str(), tokens); + auto ast = Parse(tokens); + auto asmb = GenerateByteCode(ast, source, + ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); + IPLString expected = "0: push 0\n" + "1: pop 0\n" + "2: halt\n"; + ASSERT_TRUE(asmb == expected); +} + +TEST(CodeGen, VarDeclations) +{ + IPLVector tokens; + IPLString source = "var a;"; + Tokenize(source.c_str(), tokens); + auto ast = Parse(tokens); + auto asmb = GenerateByteCode(ast, source, + ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); + IPLString expected = "0: push 1\n" + "1: pop 1\n" + "2: halt\n"; + ASSERT_TRUE(asmb == expected); +} + +TEST(CodeGen, VarDeclationsWithValue) +{ + IPLVector tokens; + IPLString source = "var a = 5;"; + Tokenize(source.c_str(), tokens); + auto ast = Parse(tokens); + auto asmb = GenerateByteCode(ast, source, + ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); + IPLString expected = "0: push 2\n" + "1: const r1 5.000000\n" + "2: mov r0 r1\n" + "3: pop 2\n" + "4: halt\n"; + ASSERT_TRUE(asmb == expected); +} + +TEST(CodeGen, VarDeclationsBinaryExpre) +{ + IPLVector tokens; + IPLString source = "var a = 5 + 6;"; + Tokenize(source.c_str(), tokens); + auto ast = Parse(tokens); + auto asmb = GenerateByteCode(ast, source, + ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); + IPLString expected = "0: push 4\n" + "1: const r1 6.000000\n" + "2: const r2 5.000000\n" + "3: add r3 r2 r1\n" + "4: mov r0 r3\n" + "5: pop 4\n" + "6: halt\n"; + + ASSERT_TRUE(asmb == expected); +} + +TEST(CodeGen, VariableAssignment) +{ + IPLVector tokens; + IPLString source = "var a; a = 5;"; + Tokenize(source.c_str(), tokens); + auto ast = Parse(tokens); + auto asmb = GenerateByteCode(ast, source, + ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); + IPLString expected = "0: push 2\n" + "1: const r1 5.000000\n" + "2: mov r0 r1\n" + "3: pop 2\n" + "4: halt\n"; + + ASSERT_TRUE(asmb == expected); +} + +TEST(CodeGen, MultiVariableAssignment) +{ + IPLVector tokens; + IPLString source = "var a; var b = 6; a = b;"; + Tokenize(source.c_str(), tokens); + auto ast = Parse(tokens); + auto asmb = GenerateByteCode(ast, source, + ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); + IPLString expected = "0: push 3\n" + "1: const r2 6.000000\n" + "2: mov r1 r2\n" + "3: mov r0 r1\n" + "4: pop 3\n" + "5: halt\n"; + + ASSERT_TRUE(asmb == expected); +} + +TEST(CodeGen, SimpleIf) +{ + IPLVector tokens; + IPLString source = "var a = 5; if (a < 1) { a = 7}"; + Tokenize(source.c_str(), tokens); + auto ast = Parse(tokens); + auto asmb = GenerateByteCode(ast, source, + ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); + IPLString expected = "0: push 5\n" + "1: const r1 5.000000\n" + "2: mov r0 r1\n" + "3: const r2 1.000000\n" + "4: less r3 r0 r2\n" + "5: jmpf r3 8\n" + "6: const r4 7.000000\n" + "7: mov r0 r4\n" + "8: pop 5\n" + "9: halt\n"; + + ASSERT_TRUE(asmb == expected); +} + +TEST(CodeGen, SimpleIfElse) +{ + IPLVector tokens; + IPLString source = "var a = 5; if (a < 1) { a = 3; } else { a = 7; }"; + Tokenize(source.c_str(), tokens); + auto ast = Parse(tokens); + auto asmb = GenerateByteCode(ast, source, + ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); + IPLString expected = "0: push 6\n" + "1: const r1 5.000000\n" + "2: mov r0 r1\n" + "3: const r2 1.000000\n" + "4: less r3 r0 r2\n" + "5: jmpf r3 9\n" + "6: const r4 3.000000\n" + "7: mov r0 r4\n" + "8: jmp 11\n" + "9: const r5 7.000000\n" + "10: mov r0 r5\n" + "11: pop 6\n" + "12: halt\n"; + + ASSERT_TRUE(asmb == expected); +} + +TEST(CodeGen, SimpleFor) +{ + IPLVector tokens; + IPLString source = "var a = 0; for (var i = 0; i < 5; i++ ){ a = a + i; }"; + Tokenize(source.c_str(), tokens); + auto ast = Parse(tokens); + auto asmb = GenerateByteCode(ast, source, + ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); + IPLString expected = "0: push 9\n" + "1: const r1 0.000000\n" + "2: mov r0 r1\n" + "3: const r3 0.000000\n" + "4: mov r2 r3\n" + "5: const r4 5.000000\n" + "6: less r5 r2 r4\n" + "7: jmpf r5 14\n" + "8: add r6 r0 r2\n" + "9: mov r0 r6\n" + "10: const r7 1.000000\n" + "11: mov r8 r2\n" + "12: add r2 r2 r7\n" + "13: jmp 5\n" + "14: pop 9\n" + "15: halt\n"; + + ASSERT_TRUE(asmb == expected); +} \ No newline at end of file -- cgit v1.3.1-23-gd82d