Can generate bytecode for files that use a decent bit of the standard library now. Need to finish implementing the external functions, and check to see why we can't print integers. I think it might be that character values aren't being generated correctly
This commit is contained in:
@@ -81,6 +81,17 @@ var printf_addr = -4
|
|||||||
var fprintf_addr = -5
|
var fprintf_addr = -5
|
||||||
var fflush_addr = -6
|
var fflush_addr = -6
|
||||||
var fgets_addr = -7
|
var fgets_addr = -7
|
||||||
|
var fopen_addr = -8
|
||||||
|
var fclose_addr = -9
|
||||||
|
var ftell_addr = -10
|
||||||
|
var fseek_addr = -11
|
||||||
|
var fread_addr = -12
|
||||||
|
var fwrite_addr = -13
|
||||||
|
var system_addr = -14
|
||||||
|
var exit_addr = -15
|
||||||
|
var popen_addr = -16
|
||||||
|
var pclose_addr = -17
|
||||||
|
var snprintf_addr = -18
|
||||||
|
|
||||||
adt operand_size {
|
adt operand_size {
|
||||||
b8,
|
b8,
|
||||||
@@ -369,6 +380,28 @@ obj bytecode_generator (Object) {
|
|||||||
instructions[p.first].imm.val = fflush_addr
|
instructions[p.first].imm.val = fflush_addr
|
||||||
else if (p.second->function.name == "fgets")
|
else if (p.second->function.name == "fgets")
|
||||||
instructions[p.first].imm.val = fgets_addr
|
instructions[p.first].imm.val = fgets_addr
|
||||||
|
else if (p.second->function.name == "fopen")
|
||||||
|
instructions[p.first].imm.val = fopen_addr
|
||||||
|
else if (p.second->function.name == "fclose")
|
||||||
|
instructions[p.first].imm.val = fclose_addr
|
||||||
|
else if (p.second->function.name == "ftell")
|
||||||
|
instructions[p.first].imm.val = ftell_addr
|
||||||
|
else if (p.second->function.name == "fseek")
|
||||||
|
instructions[p.first].imm.val = fseek_addr
|
||||||
|
else if (p.second->function.name == "fread")
|
||||||
|
instructions[p.first].imm.val = fread_addr
|
||||||
|
else if (p.second->function.name == "fwrite")
|
||||||
|
instructions[p.first].imm.val = fwrite_addr
|
||||||
|
else if (p.second->function.name == "system")
|
||||||
|
instructions[p.first].imm.val = system_addr
|
||||||
|
else if (p.second->function.name == "exit")
|
||||||
|
instructions[p.first].imm.val = exit_addr
|
||||||
|
else if (p.second->function.name == "popen")
|
||||||
|
instructions[p.first].imm.val = popen_addr
|
||||||
|
else if (p.second->function.name == "pclose")
|
||||||
|
instructions[p.first].imm.val = pclose_addr
|
||||||
|
else if (p.second->function.name == "snprintf")
|
||||||
|
instructions[p.first].imm.val = snprintf_addr
|
||||||
else
|
else
|
||||||
error("bad extern function used: " + p.second->function.name)
|
error("bad extern function used: " + p.second->function.name)
|
||||||
} else {
|
} else {
|
||||||
@@ -411,6 +444,9 @@ obj bytecode_generator (Object) {
|
|||||||
|
|
||||||
generate(node->function.body_statement)
|
generate(node->function.body_statement)
|
||||||
|
|
||||||
|
// generate a return just in case the function itself doesn't have one
|
||||||
|
generate_return_statement(ast_return_statement_ptr(null<ast_node>()))
|
||||||
|
|
||||||
instructions[push_frame_idx].addi.bi = -functions.last().frame_size
|
instructions[push_frame_idx].addi.bi = -functions.last().frame_size
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -594,6 +630,8 @@ obj bytecode_generator (Object) {
|
|||||||
}
|
}
|
||||||
// this generates the function as a value, not the actual function
|
// this generates the function as a value, not the actual function
|
||||||
fun generate_function(node: *ast_node): int {
|
fun generate_function(node: *ast_node): int {
|
||||||
|
if (!is_function(node))
|
||||||
|
error("trying to generate a function but isn't a function")
|
||||||
fixup_function_addresses.add(make_pair(instructions.size,node))
|
fixup_function_addresses.add(make_pair(instructions.size,node))
|
||||||
return emit_imm(-2)
|
return emit_imm(-2)
|
||||||
}
|
}
|
||||||
@@ -754,7 +792,7 @@ obj bytecode_generator (Object) {
|
|||||||
emit_str(0, 0, emit_addi(1, functions.last().var_to_frame_offset[struct_return_temp_ident]), size_to_operand_size(register_size))
|
emit_str(0, 0, emit_addi(1, functions.last().var_to_frame_offset[struct_return_temp_ident]), size_to_operand_size(register_size))
|
||||||
reset_reg(save_til)
|
reset_reg(save_til)
|
||||||
}
|
}
|
||||||
var return_reg = emit_call(generate_function(node->function_call.func))
|
var return_reg = emit_call(generate(node->function_call.func))
|
||||||
|
|
||||||
if (return_type->is_object() && return_type->indirection == 0) {
|
if (return_type->is_object() && return_type->indirection == 0) {
|
||||||
// if returned struct, then the struct was saved where we asked for it to be
|
// if returned struct, then the struct was saved where we asked for it to be
|
||||||
@@ -1037,7 +1075,7 @@ obj bytecode_generator (Object) {
|
|||||||
stack[-i + -1] = 0
|
stack[-i + -1] = 0
|
||||||
registers[0] = (stack-register_size) cast long // with the stack being zeroed out, this makes it a return address of 0
|
registers[0] = (stack-register_size) cast long // with the stack being zeroed out, this makes it a return address of 0
|
||||||
for (var i = main_entry.instruction_start; i < instructions.size; i++;) {
|
for (var i = main_entry.instruction_start; i < instructions.size; i++;) {
|
||||||
println(string("evaling: ") + i + ": " + to_string(instructions[i]))
|
/*println(string("evaling: ") + i + ": " + to_string(instructions[i]))*/
|
||||||
match(instructions[i]) {
|
match(instructions[i]) {
|
||||||
byte_inst::nop() {}
|
byte_inst::nop() {}
|
||||||
byte_inst::imm(i) registers[i.to_reg] = i.val
|
byte_inst::imm(i) registers[i.to_reg] = i.val
|
||||||
@@ -1087,6 +1125,21 @@ obj bytecode_generator (Object) {
|
|||||||
/*ext fun fgets(buff: *char, size: int, file: *void): *char*/
|
/*ext fun fgets(buff: *char, size: int, file: *void): *char*/
|
||||||
/*ext var stderr: *void*/
|
/*ext var stderr: *void*/
|
||||||
/*ext var stdin: *void*/
|
/*ext var stdin: *void*/
|
||||||
|
|
||||||
|
/*ext fun fopen(path: *char, mode: *char): *void*/
|
||||||
|
/*ext fun fclose(file: *void): int*/
|
||||||
|
/*ext fun ftell(file: *void): long*/
|
||||||
|
/*ext fun fseek(file: *void, offset: long, whence: int): int*/
|
||||||
|
/*ext fun fread(ptr: *void, size: ulong, nmemb: ulong, file: *void): ulong*/
|
||||||
|
/*ext fun fwrite(ptr: *void, size: ulong, nmemb: ulong, file: *void): ulong*/
|
||||||
|
|
||||||
|
/*ext fun system(call_string: *char): int*/
|
||||||
|
/*ext fun exit(code: int):void*/
|
||||||
|
|
||||||
|
/*ext fun popen(command: *char, mode: *char): *void*/
|
||||||
|
/*ext fun pclose(file: *void): int*/
|
||||||
|
|
||||||
|
/*ext fun snprintf(to_str: *char, num: ulong, format: *char, ...): int*/
|
||||||
if (func_start < 0) {
|
if (func_start < 0) {
|
||||||
if (func_start == malloc_addr)
|
if (func_start == malloc_addr)
|
||||||
registers[2] = (malloc(*(registers[0]) cast *ulong)) cast long
|
registers[2] = (malloc(*(registers[0]) cast *ulong)) cast long
|
||||||
@@ -1116,46 +1169,47 @@ obj bytecode_generator (Object) {
|
|||||||
registers[0] = registers[0] - register_size
|
registers[0] = registers[0] - register_size
|
||||||
*(registers[0]) cast *long = i + 1
|
*(registers[0]) cast *long = i + 1
|
||||||
i = func_start - 1
|
i = func_start - 1
|
||||||
print("call!")
|
/*print("call!")*/
|
||||||
println("first part of memory is (after push)")
|
/*println("call: " + functions.find_first_satisfying(fun(f: bytecode_function): bool return f.instruction_start == func_start;).name)*/
|
||||||
for (var i = 0; i < 8*8; i+=8;) {
|
/*println("first part of memory is (after push)")*/
|
||||||
print(string("-") + i + string(": "))
|
/*for (var i = 0; i < 8*8; i+=8;) {*/
|
||||||
for (var j = 0; j < 8; j++;) {
|
/*print(string("-") + i + string(": "))*/
|
||||||
if (j == 4)
|
/*for (var j = 0; j < 8; j++;) {*/
|
||||||
print(" ")
|
/*if (j == 4)*/
|
||||||
print(*(stack - (i+j)*#sizeof<uchar> - 1) cast *uchar)
|
/*print(" ")*/
|
||||||
print(" ")
|
/*print(*(stack - (i+j)*#sizeof<uchar> - 1) cast *uchar)*/
|
||||||
}
|
/*print(" ")*/
|
||||||
println()
|
/*}*/
|
||||||
}
|
/*println()*/
|
||||||
println("Done")
|
/*}*/
|
||||||
|
/*println("Done")*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
byte_inst::ret() {
|
byte_inst::ret() {
|
||||||
var pc = *(registers[0]) cast *long
|
var pc = *(registers[0]) cast *long
|
||||||
/*registers[0] += register_size*/
|
/*registers[0] += register_size*/
|
||||||
registers[0] = registers[0] + register_size
|
registers[0] = registers[0] + register_size
|
||||||
print("returning! return value is\n\t")
|
/*print("returning!")*/
|
||||||
var value = registers[2]
|
/*println("first part of memory is")*/
|
||||||
println(value)
|
/*for (var i = 0; i < 8*8; i+=8;) {*/
|
||||||
println("first part of memory is")
|
/*print(string("-") + i + string(": "))*/
|
||||||
for (var i = 0; i < 8*8; i+=8;) {
|
/*for (var j = 0; j < 8; j++;) {*/
|
||||||
print(string("-") + i + string(": "))
|
/*if (j == 4)*/
|
||||||
for (var j = 0; j < 8; j++;) {
|
/*print(" ")*/
|
||||||
if (j == 4)
|
/*print(*(stack - (i+j)*#sizeof<uchar> - 1) cast *uchar)*/
|
||||||
print(" ")
|
/*print(" ")*/
|
||||||
print(*(stack - (i+j)*#sizeof<uchar> - 1) cast *uchar)
|
/*}*/
|
||||||
print(" ")
|
/*println()*/
|
||||||
}
|
/*}*/
|
||||||
println()
|
/*println("Done")*/
|
||||||
}
|
|
||||||
println("Done")
|
|
||||||
if (pc == 0) {
|
if (pc == 0) {
|
||||||
/*println(string("got malloc is ") + *(got_malloc) cast *int)*/
|
/*println(string("got malloc is ") + *(got_malloc) cast *int)*/
|
||||||
|
var value = registers[2]
|
||||||
|
println(string("returning from main, value is ") + value)
|
||||||
return value
|
return value
|
||||||
} else {
|
} else {
|
||||||
i = pc - 1
|
i = pc - 1
|
||||||
println(string("returning to ") + pc)
|
/*println(string("returning to ") + pc)*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user