Skip to content

Commit

Permalink
binary finish
Browse files Browse the repository at this point in the history
  • Loading branch information
Jesse Chen committed Oct 8, 2023
1 parent d199e2e commit cb1a234
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 55 deletions.
45 changes: 39 additions & 6 deletions src/AST.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,53 @@ std::unique_ptr<ExpressionAST> RHS;

virtual std::vector<uint8_t> codegen() override {
std::vector<uint8_t> result;
void *pushFunPtr = runtimePtr->nativeFunction["__runtime_push__"];
void *popFunPtr = runtimePtr->nativeFunction["__runtime_pop__"];
// move LHS to R9
addAssemblyToExecutable(result, LHS->codegen());
addAssemblyToExecutable(result,mov_register_register(10U, 9U)); // LHS to 10
DEBUG("addAssemblyToExecutable(executable, mov_register_register(10, 9));");
addAssemblyToExecutable(result,mov_register_register(0U, 9U)); // LHS to 0
DEBUG("addAssemblyToExecutable(executable, mov_register_register(0, 9));");
// call push
addAssemblyToExecutable(result,insertPtrToRegister(9U, pushFunPtr));
DEBUG("addAssemblyToExecutable(executable, insertPtrToRegister(9U, pushFunPtr));");
addAssemblyToExecutable(result,callRegister(9U));
DEBUG("addAssemblyToExecutable(executable, callRegister(9U));");
// mov RHS to R9
addAssemblyToExecutable(result, RHS->codegen());
addAssemblyToExecutable(result,mov_register_register(0U, 9U)); // LHS to 0
DEBUG("addAssemblyToExecutable(executable, mov_register_register(0, 9));");
// call push
addAssemblyToExecutable(result,insertPtrToRegister(9U, pushFunPtr));
DEBUG("addAssemblyToExecutable(executable, insertPtrToRegister(9U, pushFunPtr));");
addAssemblyToExecutable(result,callRegister(9U));
DEBUG("addAssemblyToExecutable(executable, callRegister(9U));");

// call pop
addAssemblyToExecutable(result,insertPtrToRegister(9U, popFunPtr));
DEBUG("addAssemblyToExecutable(executable, insertPtrToRegister(9U, popFunPtr));");
addAssemblyToExecutable(result,callRegister(9U));
DEBUG("addAssemblyToExecutable(executable, callRegister(9U));");
// mov pop value to R10 as RHS
addAssemblyToExecutable(result,mov_register_register(10U, 0U));
DEBUG("addAssemblyToExecutable(executable, mov_register_register(10U, 0U));");

addAssemblyToExecutable(result,insertPtrToRegister(9U, popFunPtr));
DEBUG("addAssemblyToExecutable(executable, insertPtrToRegister(9U, popFunPtr));");
addAssemblyToExecutable(result,callRegister(9U));
DEBUG("addAssemblyToExecutable(executable, callRegister(9U));");
// mov pop value to R9 as LHS
addAssemblyToExecutable(result,mov_register_register(9U, 0U));
DEBUG("addAssemblyToExecutable(executable, mov_register_register(9U, 0U));");


if (op == Token::tok_positive) {
// x + y
addAssemblyToExecutable(result, add_register_register(9, 10, 9));
DEBUG("addAssemblyToExecutable(executable, add_register_register(9, 10, 9));");
addAssemblyToExecutable(result, add_register_register(9, 9, 10));
DEBUG("addAssemblyToExecutable(executable, add_register_register(9, 9, 10));");
} else if (op == Token::tok_neg) {
// x - y
addAssemblyToExecutable(result, sub_register_register(9, 10, 9));
DEBUG("addAssemblyToExecutable(executable, sub_register_register(9, 10, 9));");
addAssemblyToExecutable(result, sub_register_register(9, 9, 10));
DEBUG("addAssemblyToExecutable(executable, sub_register_register(9, 9, 10));");
} else {
throw std::runtime_error("unsupported binary operator");
}
Expand Down
16 changes: 16 additions & 0 deletions src/Runtime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
Expand All @@ -23,6 +25,18 @@ void runtime_writeln_int(int value) {
printf("%d\n", value);
}

static std::unique_ptr<std::stack<uint64_t>> runtimeStack = std::make_unique<std::stack<uint64_t>>();

static void pushStack(uint64_t value){
runtimeStack->push(value);
}

static uint64_t popStack(uint64_t value){
auto result = runtimeStack->top();
runtimeStack->pop();
return result;
}

class Runtime{
public:

Expand All @@ -31,6 +45,8 @@ class Runtime{
nativeFunction["writeln_string"] = (void*) runtime_writeln_string;
nativeFunction["write_int"] = (void*) runtime_write_int;
nativeFunction["writeln_int"] = (void*) runtime_writeln_int;
nativeFunction["__runtime_push__"] = (void*) pushStack;
nativeFunction["__runtime_pop__"] = (void*) popStack;
stringLiterals.reserve(1024*1024*8);
}

Expand Down
12 changes: 12 additions & 0 deletions tests/acceptance/binaryExpression.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
program Hello;
var a:Integer;
var b:Integer;
var c:Integer;
var d:Integer;
begin
a := 11;
b := 22;
c := 42;
d := (a+(c-b));
writeln(d);
end.
6 changes: 4 additions & 2 deletions tests/cases/binaryExpression.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
var a:Integer;
var b:Integer;
var c:Integer;
var d:Integer;
begin
a := 11;
b := 22;
c := (a+b);
writeln(c);
c := 42;
d := (a+(c-b));
writeln(d);
end.
94 changes: 47 additions & 47 deletions tests/e2e.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,58 +43,58 @@ template <typename T> void printAssemblyMachineCode(T &&runtime) {
}
}

// TEST(compiler_e2e, parser) {
// std::ifstream t(workspace / "tests" / "cases" / "binaryExpression.pas");
// std::stringstream buffer;
// buffer << t.rdbuf();
// Tokenizer tokenizer(buffer.str());
// Parser parser(tokenizer, std::make_shared<Runtime>());
// parser.debug = true;
// auto program = parser.parse();
// auto fun = createJit(program->codegen());
// std::cout << "ptr: " << std::hex << (void *)fun << std::endl;
// fun();
// // printAssemblyMachineCode(program->codegen());
// }
TEST(compiler_e2e, parser) {
std::ifstream t(workspace / "tests" / "cases" / "binaryExpression.pas");
std::stringstream buffer;
buffer << t.rdbuf();
Tokenizer tokenizer(buffer.str());
Parser parser(tokenizer, std::make_shared<Runtime>());
parser.debug = true;
auto program = parser.parse();
auto fun = createJit(program->codegen());
std::cout << "ptr: " << std::hex << (void *)fun << std::endl;
fun();
// printAssemblyMachineCode(program->codegen());
}

void mylog(char *c) { printf("%s\n", c); }

void mylogi(int c) { printf("%d\n", c); }

TEST(compiler_e2e, local_variable) {
std::vector<uint8_t> executable;
const char *test = "you are a good boy";
const char *test2 = "I am jesse";
addAssemblyToExecutable(executable, storeX29X30());
addAssemblyToExecutable(executable, mov_register_register_from_to_sp(29, 31));
addAssemblyToExecutable(executable, sub_register_imm(31, 31, 0x10));
addAssemblyToExecutable(executable, sub_register_imm(31, 31, 0x10));
addAssemblyToExecutable(executable, insertIntegerToRegister(9, 11));
addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x8));
addAssemblyToExecutable(executable, str_register_register_offset(9, 10, 0));
addAssemblyToExecutable(executable, insertIntegerToRegister(9, 22));
addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x10));
addAssemblyToExecutable(executable, str_register_register_offset(9, 10, 0));
addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x8));
addAssemblyToExecutable(executable, ldr_register_register_offset(9, 10, 0));
addAssemblyToExecutable(executable, mov_register_register(10, 9));
addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x10));
addAssemblyToExecutable(executable, ldr_register_register_offset(9, 10, 0));
addAssemblyToExecutable(executable, add_register_register(9, 10, 9));
addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x18));
addAssemblyToExecutable(executable, str_register_register_offset(9, 10, 0));
addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x18));
addAssemblyToExecutable(executable, ldr_register_register_offset(9, 10, 0));
addAssemblyToExecutable(executable, mov_register_register(0, 9));
addAssemblyToExecutable(executable, insertPtrToRegister(9, (void *)mylogi));
addAssemblyToExecutable(executable, callRegister(9));
addAssemblyToExecutable(executable, mov_register_register_from_to_sp(31, 29));
addAssemblyToExecutable(executable, loadX29X30());
addAssemblyToExecutable(executable, ret());
auto fun = createJit(executable);
// std::cout << "ptr: 0x" << std::hex<< (void*) fun << std::endl;
fun();
}
// TEST(compiler_e2e, local_variable) {
// std::vector<uint8_t> executable;
// const char *test = "you are a good boy";
// const char *test2 = "I am jesse";
// addAssemblyToExecutable(executable, storeX29X30());
// addAssemblyToExecutable(executable, mov_register_register_from_to_sp(29, 31));
// addAssemblyToExecutable(executable, sub_register_imm(31, 31, 0x10));
// addAssemblyToExecutable(executable, sub_register_imm(31, 31, 0x10));
// addAssemblyToExecutable(executable, insertIntegerToRegister(9, 11));
// addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x8));
// addAssemblyToExecutable(executable, str_register_register_offset(9, 10, 0));
// addAssemblyToExecutable(executable, insertIntegerToRegister(9, 22));
// addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x10));
// addAssemblyToExecutable(executable, str_register_register_offset(9, 10, 0));
// addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x8));
// addAssemblyToExecutable(executable, ldr_register_register_offset(9, 10, 0));
// addAssemblyToExecutable(executable, mov_register_register(10, 9));
// addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x10));
// addAssemblyToExecutable(executable, ldr_register_register_offset(9, 10, 0));
// addAssemblyToExecutable(executable, add_register_register(9, 10, 9));
// addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x18));
// addAssemblyToExecutable(executable, str_register_register_offset(9, 10, 0));
// addAssemblyToExecutable(executable, sub_register_imm(10, 29, 0x18));
// addAssemblyToExecutable(executable, ldr_register_register_offset(9, 10, 0));
// addAssemblyToExecutable(executable, mov_register_register(0, 9));
// addAssemblyToExecutable(executable, insertPtrToRegister(9, (void *)mylogi));
// addAssemblyToExecutable(executable, callRegister(9));
// addAssemblyToExecutable(executable, mov_register_register_from_to_sp(31, 29));
// addAssemblyToExecutable(executable, loadX29X30());
// addAssemblyToExecutable(executable, ret());
// auto fun = createJit(executable);
// // std::cout << "ptr: 0x" << std::hex<< (void*) fun << std::endl;
// fun();
// }

// TEST(compiler_e2e, variable) {
// std::vector<uint8_t> result;
Expand Down

0 comments on commit cb1a234

Please sign in to comment.