Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/tasm/tasm_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ typedef struct tasm_ast{
AST_OP_DEREF,
AST_OP_DEREFB,
AST_OP_HSET,
AST_OP_HSETOF,
AST_OP_PUTS,
AST_OP_PUTC,
AST_OP_NATIVE,
Expand Down Expand Up @@ -401,6 +402,12 @@ void tasm_ast_show(tasm_ast_t* node, int indent) {
case AST_OP_HALLOC:
printf("HALLOC\n");
break;
case AST_OP_HSET:
printf("HSET\n");
break;
case AST_OP_HSETOF:
printf("HSETOF\n");
break;
case AST_OP_PUTS:
printf("PUTS\n");
break;
Expand Down
6 changes: 3 additions & 3 deletions include/tasm/tasm_lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ tasm_token_t tasm_lexer_collect_binary_number(tasm_lexer_t *lexer) {
return token;
}

const size_t _inst_strings_count = 62;
const size_t _inst_strings_count = 63;

const char* _inst_strings_lower[] = {
"nop", "push", "pop",
Expand All @@ -375,7 +375,7 @@ const char* _inst_strings_lower[] = {
"and", "or", "not",
"band", "bor", "bnot", "lshft", "rshft",
"loadc", "aloadc", "load", "store", "gload", "gstore",
"halloc", "deref", "derefb", "hset",
"halloc", "deref", "derefb", "hset", "hsetof",
"puts", "putc",
"native",
"hlt"
Expand All @@ -394,7 +394,7 @@ const char* _inst_strings_upper[] = {
"AND", "OR", "NOT",
"BAND", "BOR", "BNOT", "LSHFT", "RSHFT",
"LOADC", "ALOADC", "LOAD", "STORE", "GLOAD", "GSTORE",
"HALLOC", "DEREF", "DEREFB", "HSET",
"HALLOC", "DEREF", "DEREFB", "HSET", "HSETOF",
"PUTS", "PUTC",
"NATIVE",
"HLT"
Expand Down
2 changes: 2 additions & 0 deletions include/tasm/tasm_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,8 @@ tasm_ast_t* tasm_parse_instruction(tasm_parser_t* parser) {
break;
case TOKEN_OP_HSET: tag = AST_OP_HSET;
break;
case TOKEN_OP_HSETOF: tag = AST_OP_HSETOF;
break;
case TOKEN_OP_PUTS: tag = AST_OP_PUTS;
break;
case TOKEN_OP_PUTC: tag = AST_OP_PUTC;
Expand Down
1 change: 1 addition & 0 deletions include/tasm/tasm_token.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ typedef enum {
TOKEN_OP_DEREF,
TOKEN_OP_DEREFB,
TOKEN_OP_HSET,
TOKEN_OP_HSETOF,
TOKEN_OP_PUTS,
TOKEN_OP_PUTC,
TOKEN_OP_NATIVE,
Expand Down
4 changes: 4 additions & 0 deletions include/tasm/tasm_translator.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ case AST_OP_HALLOC: \
case AST_OP_DEREF: \
case AST_OP_DEREFB: \
case AST_OP_HSET: \
case AST_OP_HSETOF: \
case AST_OP_PUTS: \
case AST_OP_PUTC: \
case AST_OP_NATIVE: \
Expand Down Expand Up @@ -493,6 +494,9 @@ static void tasm_translate_line(tasm_translator_t* translator, tasm_ast_t* node,
case AST_OP_HSET:
program_push(translator, (opcode_t){.type = OP_HSET});
break;
case AST_OP_HSETOF:
program_push(translator, (opcode_t){.type = OP_HSETOF});
break;
case AST_OP_PUTS:
program_push(translator, (opcode_t){.type = OP_PUTS});
break;
Expand Down
32 changes: 31 additions & 1 deletion include/tvm/tvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ typedef enum {
OP_DEREF,
OP_DEREFB, // deref for a spesific byte-sized object
OP_HSET,
OP_HSETOF, // offset version of hset

/* print to standart output */
OP_PUTS,
Expand Down Expand Up @@ -908,7 +909,7 @@ exception_t tvm_exec_opcode(tvm_t* vm) {
}
vm->ip++;
break;
case OP_HSET:
case OP_HSET: {
if (vm->sp < 4)
return EXCEPT_STACK_UNDERFLOW;
uint32_t byte_size = vm->stack[vm->sp - 1].i32; // byte_size
Expand Down Expand Up @@ -940,6 +941,35 @@ exception_t tvm_exec_opcode(tvm_t* vm) {
vm->sp -= 4;
vm->ip++;
break;
}
case OP_HSETOF: {
if (vm->sp < 4)
return EXCEPT_STACK_UNDERFLOW;
uint32_t type_size = vm->stack[vm->sp - 1].i32; // type_size
uint32_t offset = vm->stack[vm->sp - 2].i32; // offset
gc_block* addr = (gc_block*)(vm->stack[vm->sp - 3].ui64); // beginning address of the value (it should be)

uint64_t size = addr->size;
if (offset >= size) {
return EXCEPT_INVALID_ARRAY_INDEX; // FIXME: here with a correct runtime error
}

switch (type_size)
{
#ifdef __x86_64__
case sizeof(uint32_t): *(uint32_t*)(addr->value + offset) = vm->stack[vm->sp - 4].ui32; break;
case sizeof(uint8_t): *(uint8_t*)(addr->value + offset) = vm->stack[vm->sp - 4].ui8; break;
case sizeof(uint64_t): *(uint64_t*)(addr->value + offset) = vm->stack[vm->sp - 4].ui64; break;
#elif defined(__i386__)
case sizeof(uint32_t): *(uint32_t*)((uint32_t*)addr->value + offset) = vm->stack[vm->sp - 4].ui32; break;
case sizeof(uint8_t): *(uint8_t*)((uint8_t*)addr->value + offset) = vm->stack[vm->sp - 4].ui8; break;
#endif
default: return EXCEPT_INVALID_PRIMITIVE_SIZE;
}
vm->sp -= 4;
vm->ip++;
break;
}
case OP_PUTS:
if (vm->sp < 1)
return EXCEPT_STACK_UNDERFLOW;
Expand Down