commit c12bff5f13ecdcc73bd4048a6ee129f9bcec28c8 parent 8bc7df5ac15066a333c4723dfca1da814729fb69 Author: Paul Longtine <paullongtine@gmail.com> Date: Thu Mar 10 13:55:31 2016 More progress. Diffstat: doc/SPECIFICATION | 10 +- src/vm/Makefile | 2 +- src/vm/inc/ins_def.h | 8 +- src/vm/inc/ins_mdata.h | 12 ++- src/vm/inc/var.h | 20 ++-- src/vm/inc/var_ops.h | 29 ++++++- src/vm/src/bc.c | 2 +- src/vm/src/ins_def.c | 138 ++++++++++++++++++++++++++--- src/vm/src/proc.c | 5 +- src/vm/src/var.c | 63 ++++++------- src/vm/src/var_ops.c | 195 +++++++++++++++++++++++++++++++++++++++++- src/vm/tests/bytecodes/looptest | Bin 0 -> 12 bytes 12 files changed, 425 insertions(+), 59 deletions(-)
diff --git a/doc/SPECIFICATION b/doc/SPECIFICATION @@ -125,7 +125,7 @@ Keywords: 20 DEC S<scope> S<type> N<ref> - declare variable of type 21 LOV S<scope> N<ref> - loads reference variable on to stack 22 STV S<scope> N<ref> - stores TOS to reference variable -23 LOC S<scope> N<ref> D<data> - loads constant into variable +23 CTV S<scope> N<ref> D<data> - loads constant into variable 24 CTS D<data> - loads constant into stack ------------------------------------------------------------------------------- 3 - Type management @@ -174,7 +174,7 @@ to TOS 60 STARTL - Start of loop 61 CLOOP - Conditional loop. If TOS is true, continue looping, else break 6E BREAK - Breaks out of loop -6F DONE - End of loop +6F ENDL - End of loop ------------------------------------------------------------------------------- 7 - Code flow @@ -182,6 +182,10 @@ to TOS ------------------------------------------------------------------------------- 70 GOTO A<addr> - Goes to address 71 JUMPF A<n> - Goes forward <n> lines +72 IFDO - If TOS is TRUE, do until done, if not, jump to done +73 ELSE - Chained with an IFDO statement, if IFDO fails, execute ELSE + block until DONE is reached. +7E DONE - End of block 7F CALL N<ref> - Calls function, pushes return value on to STACK. ------------------------------------------------------------------------------- 8 - Manipulating High-order Object Variables @@ -224,6 +228,8 @@ F0 RETURN - Returns from function 02 PRINT - Prints whatever is on the TOS. +03 FREE - Pops & Deletes TOS + 0E ARGB - Builds arguement stack 0F LIBC A<ref> - Library call diff --git a/src/vm/Makefile b/src/vm/Makefile @@ -10,6 +10,7 @@ DEPS = $(INC_DIR)/is_mdata.h \ bc.h \ is.h \ var.h \ + var_ops.h \ stk.h \ ht.h \ ns.h \ @@ -23,6 +24,7 @@ OBJ = $(SRC_DIR)/main.o \ $(SRC_DIR)/bc.o \ $(SRC_DIR)/is.o \ $(SRC_DIR)/var.o \ + $(SRC_DIR)/var_ops.o \ $(SRC_DIR)/stk.o \ $(SRC_DIR)/ht.o \ $(SRC_DIR)/ns.o \ diff --git a/src/vm/inc/ins_def.h b/src/vm/inc/ins_def.h @@ -12,6 +12,7 @@ #include "bc.h" #include "stk.h" #include "var.h" +#include "var_ops.h" #include "pc.h" #include "helper.h" @@ -42,7 +43,7 @@ void _ins_def_ROT_THREE(rt_t*, bc_cont*); void _ins_def_DEC (rt_t*, bc_cont*); void _ins_def_LOV (rt_t*, bc_cont*); void _ins_def_STV (rt_t*, bc_cont*); -void _ins_def_LOC (rt_t*, bc_cont*); +void _ins_def_CTV (rt_t*, bc_cont*); void _ins_def_CTS (rt_t*, bc_cont*); void _ins_def_TYPEOF (rt_t*, bc_cont*); @@ -73,10 +74,13 @@ void _ins_def_NOT (rt_t*, bc_cont*); void _ins_def_STARTL (rt_t*, bc_cont*); void _ins_def_CLOOP (rt_t*, bc_cont*); void _ins_def_BREAK (rt_t*, bc_cont*); -void _ins_def_DONE (rt_t*, bc_cont*); +void _ins_def_ENDL (rt_t*, bc_cont*); void _ins_def_GOTO (rt_t*, bc_cont*); void _ins_def_JUMPF (rt_t*, bc_cont*); +void _ins_def_IFDO (rt_t*, bc_cont*); +void _ins_def_ELSE (rt_t*, bc_cont*); +void _ins_def_DONE (rt_t*, bc_cont*); void _ins_def_CALL (rt_t*, bc_cont*); void _ins_def_PUSH (rt_t*, bc_cont*); diff --git a/src/vm/inc/ins_mdata.h b/src/vm/inc/ins_mdata.h @@ -67,10 +67,13 @@ /* STARTL */ INS_MDATA[0x60] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ /* CLOOP */ INS_MDATA[0x61] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ /* BREAK */ INS_MDATA[0x6E] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ -/* DONE */ INS_MDATA[0x6F] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* ENDL */ INS_MDATA[0x6F] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ \ /* GOTO */ INS_MDATA[0x70] = encode(1, A_ADDR, A_BYTE, A_BYTE); \ /* JUMPF */ INS_MDATA[0x71] = encode(1, A_BYTE, A_BYTE, A_BYTE); \ +/* IFDO */ INS_MDATA[0x72] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* ELSE */ INS_MDATA[0x73] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* DONE */ INS_MDATA[0x7E] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ /* CALL */ INS_MDATA[0x7F] = encode(1, A_ADDR, A_BYTE, A_BYTE); \ \ /* PUSH */ INS_MDATA[0x80] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ @@ -108,7 +111,7 @@ /* DEC */ INS_ADATA[0x20] = encode(3, BTOI, BTOI, BTOI); \ /* LOV */ INS_ADATA[0x21] = encode(2, BTOI, BTOI, BTOI); \ /* STV */ INS_ADATA[0x22] = encode(2, BTOI, BTOI, BTOI); \ -/* LOC */ INS_ADATA[0x23] = encode(3, BTOI, BTOI, BTOI); \ +/* CTV */ INS_ADATA[0x23] = encode(3, BTOI, BTOI, BTOI); \ /* CTS */ INS_ADATA[0x24] = encode(1, DTOV, BTOI, BTOI); \ \ /* TYPEOF */ INS_ADATA[0x30] = encode(0, BTOI, BTOI, BTOI); \ @@ -139,10 +142,13 @@ /* STARTL */ INS_ADATA[0x60] = encode(0, BTOI, BTOI, BTOI); \ /* CLOOP */ INS_ADATA[0x61] = encode(0, BTOI, BTOI, BTOI); \ /* BREAK */ INS_ADATA[0x6E] = encode(0, BTOI, BTOI, BTOI); \ -/* DONE */ INS_ADATA[0x6F] = encode(0, BTOI, BTOI, BTOI); \ +/* ENDL */ INS_ADATA[0x6F] = encode(0, BTOI, BTOI, BTOI); \ \ /* GOTO */ INS_ADATA[0x70] = encode(1, BTOI, BTOI, BTOI); \ /* JUMPF */ INS_ADATA[0x71] = encode(1, BTOI, BTOI, BTOI); \ +/* IFDO */ INS_ADATA[0x72] = encode(0, BTOI, BTOI, BTOI); \ +/* ELSE */ INS_ADATA[0x73] = encode(0, BTOI, BTOI, BTOI); \ +/* DONE */ INS_ADATA[0x7E] = encode(0, BTOI, BTOI, BTOI); \ /* CALL */ INS_ADATA[0x7F] = encode(1, BTOI, BTOI, BTOI); \ \ /* PUSH */ INS_ADATA[0x80] = encode(0, BTOI, BTOI, BTOI); \ diff --git a/src/vm/inc/var.h b/src/vm/inc/var.h @@ -25,7 +25,7 @@ typedef enum { G_STR, // 9 S_ARRAY,// A D_ARRAY,// B - K_ARRAY,// C + H_TABLE,// C G_FIFO // D } b_type; @@ -38,6 +38,10 @@ typedef struct var_data_type { b_type v; } var_data_type; +typedef struct var_data_plist { + b_type* v; +} var_data_plist; + typedef struct var_data_func { bc_addr loc; bc_addr end; @@ -63,9 +67,10 @@ typedef struct var_data_str { char* v; } var_data_str; -typedef struct var_data_plist { - b_type* v; -} var_data_plist; +typedef struct var_data_array { + size_t size; + var_cont* v; +} var_data_array; #include "bc.h" @@ -74,21 +79,22 @@ typedef struct var_data_plist { var_cont* var_new(b_type); void* var_data_alloc_TYPE(b_type); +void* var_data_alloc_PLIST(size_t); void* var_data_alloc_FUNC(b_type); void* var_data_alloc_G_INT(int); void* var_data_alloc_G_FLOAT(double); void* var_data_alloc_G_CHAR(char); void* var_data_alloc_G_STR(size_t); -void* var_data_alloc_PLIST(size_t); +void* var_data_alloc_S_ARRAY(size_t); /* Frees variable */ void var_del(var_cont*); void var_data_free(void*, b_type); +void var_data_free_PLIST(void*); void var_data_free_FUNC(void*); void var_data_free_G_STR(void*); -void var_data_free_PLIST(void*); /* Sets variable * void* -> pointer to allocated space of memory that agrees with b_type @@ -115,7 +121,7 @@ var_cont* var_data_cpy(var_cont*); * int - sizeof(bytes) * byte_t* - array of bytes */ -var_cont* bytes_to_int(int, byte_t*); +var_cont* raw_to_int(int, byte_t*); /* Byte to b_type. * byte_t - value maps to enum b_type diff --git a/src/vm/inc/var_ops.h b/src/vm/inc/var_ops.h @@ -0,0 +1,29 @@ +/* `var_ops.h` -> Operate on variables. + */ + +#ifndef VAR_OPS_H +#define VAR_OPS_H + +#include <stdlib.h> +#include <stdio.h> + +#include "var.h" +#include "helper.h" + +var_cont* var_add_float(var_cont*, var_cont*); +var_cont* var_add_int(var_cont*, var_cont*); +var_cont* var_add(var_cont*, var_cont*); + +var_cont* var_sub_float(var_cont*, var_cont*); +var_cont* var_sub_int(var_cont*, var_cont*); +var_cont* var_sub(var_cont*, var_cont*); + +var_cont* var_mult_float(var_cont*, var_cont*); +var_cont* var_mult_int(var_cont*, var_cont*); +var_cont* var_mult(var_cont*, var_cont*); + +var_cont* var_div_float(var_cont*, var_cont*); +var_cont* var_div_int(var_cont*, var_cont*); +var_cont* var_div(var_cont*, var_cont*); + +#endif //VAR_OPS_H diff --git a/src/vm/src/bc.c b/src/vm/src/bc.c @@ -144,7 +144,7 @@ void process_args(bc_cont* ins) { if (arg_types[x] == BTOI) { - ins->varg[x] = bytes_to_int(ins->sarg[x], ins->args[x]); + ins->varg[x] = raw_to_int(ins->sarg[x], ins->args[x]); } else if (arg_types[x] == BTOT) { diff --git a/src/vm/src/ins_def.c b/src/vm/src/ins_def.c @@ -8,6 +8,7 @@ #include "bc.h" #include "stk.h" #include "var.h" +#include "var_ops.h" #include "pc.h" #include "helper.h" @@ -30,7 +31,7 @@ void init_ins_def( void ) INS_DEF[0x20] = _ins_def_DEC; INS_DEF[0x21] = _ins_def_LOV; INS_DEF[0x22] = _ins_def_STV; - INS_DEF[0x23] = _ins_def_LOC; + INS_DEF[0x23] = _ins_def_CTV; INS_DEF[0x24] = _ins_def_CTS; INS_DEF[0x30] = _ins_def_TYPEOF; @@ -61,10 +62,11 @@ void init_ins_def( void ) INS_DEF[0x60] = _ins_def_STARTL; INS_DEF[0x61] = _ins_def_CLOOP; INS_DEF[0x6E] = _ins_def_BREAK; - INS_DEF[0x6F] = _ins_def_DONE; + INS_DEF[0x6F] = _ins_def_ENDL; INS_DEF[0x70] = _ins_def_GOTO; INS_DEF[0x71] = _ins_def_JUMPF; + INS_DEF[0x7E] = _ins_def_DONE; INS_DEF[0x7F] = _ins_def_CALL; INS_DEF[0x80] = _ins_def_PUSH; @@ -127,16 +129,10 @@ void _ins_def_POP (rt_t* ctx, bc_cont* line) int n = var_data_get_G_INT(line->varg[0]); int i = 0; - var_cont* var; - while (n > i) { i++; - - var = stk_pop(&ctx->stack); - - if (var != NULL) - var_del(var); + stk_pop(&ctx->stack); } pc_inc(ctx->pc, 1); @@ -162,18 +158,46 @@ void _ins_def_ROT_THREE(rt_t* ctx, bc_cont* line) void _ins_def_DEC (rt_t* ctx, bc_cont* line) { + int scope = var_data_get_G_INT(line->varg[0]); + int type = var_data_get_G_INT(line->varg[1]); + int name = var_data_get_G_INT(line->varg[2]); + + proc_decvar(ctx, type, scope, name); + pc_inc(ctx->pc, 1); } void _ins_def_LOV (rt_t* ctx, bc_cont* line) { + int scope = var_data_get_G_INT(line->varg[0]); + int name = var_data_get_G_INT(line->varg[1]); + + var_cont* var; + + var = proc_getvar(ctx, scope, name); + + stk_push(&ctx->stack, var); + pc_inc(ctx->pc, 1); } void _ins_def_STV (rt_t* ctx, bc_cont* line) { + int scope = var_data_get_G_INT(line->varg[0]); + int name = var_data_get_G_INT(line->varg[1]); + + var_cont* var = stk_pop(&ctx->stack); + + proc_setvar(ctx, scope, name, var); + pc_inc(ctx->pc, 1); } -void _ins_def_LOC (rt_t* ctx, bc_cont* line) +void _ins_def_CTV (rt_t* ctx, bc_cont* line) { + int scope = var_data_get_G_INT(line->varg[0]); + int name = var_data_get_G_INT(line->varg[1]); + var_cont* var = line->varg[2]; + + proc_setvar(ctx, scope, name, var); + pc_inc(ctx->pc, 1); } void _ins_def_CTS (rt_t* ctx, bc_cont* line) @@ -184,6 +208,15 @@ void _ins_def_CTS (rt_t* ctx, bc_cont* line) void _ins_def_TYPEOF (rt_t* ctx, bc_cont* line) { + var_cont* var = stk_at(ctx->stack, 0); + var_cont* new = var_new(TYPE); + + var_data_type* data = var_data_alloc_TYPE(var->type); + + var_set(new, data, TYPE); + + stk_push(&ctx->stack, new); + pc_inc(ctx->pc, 1); } void _ins_def_CAST (rt_t* ctx, bc_cont* line) @@ -193,18 +226,46 @@ void _ins_def_CAST (rt_t* ctx, bc_cont* line) void _ins_def_ADD (rt_t* ctx, bc_cont* line) { + var_cont* A = stk_pop(&ctx->stack); + var_cont* B = stk_pop(&ctx->stack); + + var_cont* var = var_add(A, B); + + stk_push(&ctx->stack, var); + pc_inc(ctx->pc, 1); } void _ins_def_SUB (rt_t* ctx, bc_cont* line) { + var_cont* A = stk_pop(&ctx->stack); + var_cont* B = stk_pop(&ctx->stack); + + var_cont* var = var_sub(A, B); + + stk_push(&ctx->stack, var); + pc_inc(ctx->pc, 1); } void _ins_def_MULT (rt_t* ctx, bc_cont* line) { + var_cont* A = stk_pop(&ctx->stack); + var_cont* B = stk_pop(&ctx->stack); + + var_cont* var = var_mult(A, B); + + stk_push(&ctx->stack, var); + pc_inc(ctx->pc, 1); } void _ins_def_DIV (rt_t* ctx, bc_cont* line) { + var_cont* A = stk_pop(&ctx->stack); + var_cont* B = stk_pop(&ctx->stack); + + var_cont* var = var_mult(A, B); + + stk_push(&ctx->stack, var); + pc_inc(ctx->pc, 1); } void _ins_def_POW (rt_t* ctx, bc_cont* line) @@ -266,6 +327,10 @@ void _ins_def_LTHAN (rt_t* ctx, bc_cont* line) } void _ins_def_EQ (rt_t* ctx, bc_cont* line) { + var_cont* A = stk_pop(&ctx->stack); + var_cont* B = stk_pop(&ctx->stack); + + pc_inc(ctx->pc, 1); } void _ins_def_NOT (rt_t* ctx, bc_cont* line) @@ -275,19 +340,38 @@ void _ins_def_NOT (rt_t* ctx, bc_cont* line) void _ins_def_STARTL (rt_t* ctx, bc_cont* line) { + pc_branch(ctx->pc, ctx->pc->stk->address); pc_inc(ctx->pc, 1); } void _ins_def_CLOOP (rt_t* ctx, bc_cont* line) { - pc_inc(ctx->pc, 1); + var_cont* var = stk_pop(&ctx->stack); + + int value = var_data_get_G_INT(var); + + if (value <= 0) + { + pc_return(ctx->pc); + while (pc_safe(ctx->pc)) + { + pc_update(ctx->pc); + pc_inc(ctx->pc, 1); + + if (ctx->pc->line->op == 0x6F) + { + break; + } + } + } } void _ins_def_BREAK (rt_t* ctx, bc_cont* line) { + pc_inc(ctx->pc, 1); } -void _ins_def_DONE (rt_t* ctx, bc_cont* line) +void _ins_def_ENDL (rt_t* ctx, bc_cont* line) { - pc_inc(ctx->pc, 1); + pc_return(ctx->pc); } void _ins_def_GOTO (rt_t* ctx, bc_cont* line) @@ -298,6 +382,34 @@ void _ins_def_JUMPF (rt_t* ctx, bc_cont* line) { pc_inc(ctx->pc, 1); } +void _ins_def_IFDO (rt_t* ctx, bc_cont* line) +{ + var_cont* var = stk_pop(&ctx->stack); + + int value = var_data_get_G_INT(var); + + if (value <= 0) + { + while (pc_safe(ctx->pc)) + { + pc_update(ctx->pc); + pc_inc(ctx->pc, 1); + + if (ctx->pc->line->op == 0x73) + { + break; + } else + if (ctx->pc->line->op == 0x7E) + { + break; + } + } + } +} +void _ins_def_DONE (rt_t* ctx, bc_cont* line) +{ + pc_inc(ctx->pc, 1); +} void _ins_def_CALL (rt_t* ctx, bc_cont* line) { pc_inc(ctx->pc, 1); diff --git a/src/vm/src/proc.c b/src/vm/src/proc.c @@ -34,7 +34,7 @@ void proc_run(rt_t* ctx) for (n = 0; pc_safe(ctx->pc); pc_update(ctx->pc)) { - printf("%i - %i: %x\n", n, ctx->pc->stk->address, ctx->pc->line->op); + //printf("%i - %i: %x\n", n, ctx->pc->stk->address, ctx->pc->line->op); INS_DEF[ctx->pc->line->op](ctx, ctx->pc->line); @@ -73,6 +73,7 @@ var_cont* proc_callfun(rt_t* ctx, var_cont* func) */ void proc_decvar(rt_t* ctx, b_type type, int scope, ns_addr name) { + N_ASSERT(ctx); ns_dec(ctx->vars, type, scope, name); } @@ -86,6 +87,7 @@ void proc_decvar(rt_t* ctx, b_type type, int scope, ns_addr name) */ void proc_setvar(rt_t* ctx, int scope, ns_addr name, var_cont* var) { + N_ASSERT(ctx); ns_set(ctx->vars, scope, name, var); } @@ -96,6 +98,7 @@ void proc_setvar(rt_t* ctx, int scope, ns_addr name, var_cont* var) */ var_cont* proc_getvar(rt_t* ctx, int scope, ns_addr name) { + N_ASSERT(ctx); var_cont* rv; rv = ns_get(ctx->vars, scope, name); diff --git a/src/vm/src/var.c b/src/vm/src/var.c @@ -16,6 +16,16 @@ void* var_data_alloc_TYPE(b_type type) return rv; } +void* var_data_alloc_PLIST(size_t size) +{ + var_data_plist* rv = (var_data_plist*)malloc(sizeof(var_data_plist)); + M_ASSERT(rv); + + rv->v = (b_type*)malloc(sizeof(b_type)*size); + + return rv; +} + void* var_data_alloc_FUNC(b_type type) { var_data_func* rv = (var_data_func*)malloc(sizeof(var_data_func)); @@ -71,16 +81,6 @@ void* var_data_alloc_G_STR(size_t size) return rv; } -void* var_data_alloc_PLIST(size_t size) -{ - var_data_plist* rv = (var_data_plist*)malloc(sizeof(var_data_plist)); - M_ASSERT(rv); - - rv->v = (b_type*)malloc(sizeof(b_type)*size); - - return rv; -} - var_cont* var_new(b_type type) { var_cont* new = (var_cont*)malloc(sizeof(var_cont)); @@ -126,25 +126,24 @@ void var_data_free(void* data, b_type type) free(data); } +void var_data_free_PLIST(void* data) +{ + var_data_plist* d = data; + if (d->v != NULL) + free(d->v); +} void var_data_free_FUNC(void* data) { var_data_func* d = data; if (d->param != NULL) free(d->param); } - void var_data_free_G_STR(void* data) { var_data_str* d = data; if (d->v != NULL) free(d->v); } -void var_data_free_PLIST(void* data) -{ - var_data_plist* d = data; - if (d->v != NULL) - free(d->v); -} void var_set(var_cont* var, void* data, b_type type) { @@ -170,6 +169,18 @@ b_type var_data_get_TYPE(var_cont* var) return t->v; } +b_type* var_data_get_PLIST(var_cont* var) +{ + N_ASSERT(var); + ASSERT( var->type == PLIST, "TypeError" ); + + N_ASSERT(var->data); + + var_data_plist* t = var->data; + + return t->v; +} + var_data_func* var_data_get_FUNC(var_cont* var) { N_ASSERT(var); @@ -228,18 +239,6 @@ char* var_data_get_G_STR(var_cont* var) return t->v; } -b_type* var_data_get_PLIST(var_cont* var) -{ - N_ASSERT(var); - ASSERT( var->type == PLIST, "TypeError" ); - - N_ASSERT(var->data); - - var_data_plist* t = var->data; - - return t->v; -} - void* var_data_cpy_G_INT(var_data_int* data) { var_data_int* rv = var_data_alloc_G_INT(data->v); @@ -314,7 +313,7 @@ var_cont* var_data_cpy(var_cont* var) * int - sizeof(bytes) * byte_t* - array of bytes */ -var_cont* bytes_to_int(int size, byte_t* bytes) +var_cont* raw_to_int(int size, byte_t* bytes) { var_cont* rv = var_new(G_INT); @@ -394,6 +393,10 @@ var_cont* raw_to_var(int n, byte_t* bytes) byte_t* data = ++bytes; + if (type == G_INT) + { + rv->data = raw_to_int(n - 1, data); + } else if (type == G_STR) { rv->data = raw_to_str(n - 1, data); diff --git a/src/vm/src/var_ops.c b/src/vm/src/var_ops.c @@ -0,0 +1,195 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "var_ops.h" + +#include "var.h" +#include "helper.h" + +var_cont* var_add_float(var_cont* A, var_cont* B) +{ + var_cont* var = var_new(G_FLOAT); + double AV = var_data_get_G_FLOAT(A); + double BV = var_data_get_G_FLOAT(B); + + double S = AV + BV; + + var_data_float* data = var_data_alloc_G_FLOAT(S); + + var_set(var, data, G_FLOAT); + + return var; +} +var_cont* var_add_int(var_cont* A, var_cont* B) +{ + var_cont* var = var_new(G_INT); + int AV = var_data_get_G_INT(A); + int BV = var_data_get_G_INT(B); + + int S = AV + BV; + + var_data_int* data = var_data_alloc_G_INT(S); + + var_set(var, data, G_INT); + + return var; +} +var_cont* var_add(var_cont* A, var_cont* B) +{ + var_cont* rv; + + ASSERT(( A->type == B->type ), "Inconsistent Types\n"); + if (A->type == G_INT && B->type == G_INT) + { + rv = var_add_int(A, B); + } else + if (A->type == G_FLOAT && B->type == G_FLOAT) + { + rv = var_add_float(A, B); + } + + N_ASSERT(rv); + + return rv; +} + +var_cont* var_sub_float(var_cont* A, var_cont* B) +{ + var_cont* var = var_new(G_FLOAT); + double AV = var_data_get_G_FLOAT(A); + double BV = var_data_get_G_FLOAT(B); + + double S = AV - BV; + + var_data_float* data = var_data_alloc_G_FLOAT(S); + + var_set(var, data, G_FLOAT); + + return var; +} +var_cont* var_sub_int(var_cont* A, var_cont* B) +{ + var_cont* var = var_new(G_INT); + int AV = var_data_get_G_INT(A); + int BV = var_data_get_G_INT(B); + + int S = AV - BV; + + var_data_int* data = var_data_alloc_G_INT(S); + + var_set(var, data, G_INT); + + return var; +} +var_cont* var_sub(var_cont* A, var_cont* B) +{ + var_cont* rv; + + ASSERT(( A->type == B->type ), "Inconsistent Types\n"); + if (A->type == G_INT && B->type == G_INT) + { + rv = var_sub_int(A, B); + } else + if (A->type == G_FLOAT && B->type == G_FLOAT) + { + rv = var_sub_float(A, B); + } + + N_ASSERT(rv); + + return rv; +} + +var_cont* var_mult_float(var_cont* A, var_cont* B) +{ + var_cont* var = var_new(G_FLOAT); + double AV = var_data_get_G_FLOAT(A); + double BV = var_data_get_G_FLOAT(B); + + double S = AV * BV; + + var_data_float* data = var_data_alloc_G_FLOAT(S); + + var_set(var, data, G_FLOAT); + + return var; +} +var_cont* var_mult_int(var_cont* A, var_cont* B) +{ + var_cont* var = var_new(G_INT); + int AV = var_data_get_G_INT(A); + int BV = var_data_get_G_INT(B); + + int S = AV * BV; + + var_data_int* data = var_data_alloc_G_INT(S); + + var_set(var, data, G_INT); + + return var; +} +var_cont* var_mult(var_cont* A, var_cont* B) +{ + var_cont* rv; + + ASSERT(( A->type == B->type ), "Inconsistent Types\n"); + if (A->type == G_INT && B->type == G_INT) + { + rv = var_mult_int(A, B); + } else + if (A->type == G_FLOAT && B->type == G_FLOAT) + { + rv = var_mult_float(A, B); + } + + N_ASSERT(rv); + + return rv; +} + +var_cont* var_div_float(var_cont* A, var_cont* B) +{ + var_cont* var = var_new(G_FLOAT); + double AV = var_data_get_G_FLOAT(A); + double BV = var_data_get_G_FLOAT(B); + + double S = AV * BV; + + var_data_float* data = var_data_alloc_G_FLOAT(S); + + var_set(var, data, G_FLOAT); + + return var; +} +var_cont* var_div_int(var_cont* A, var_cont* B) +{ + var_cont* var = var_new(G_INT); + int AV = var_data_get_G_INT(A); + int BV = var_data_get_G_INT(B); + + int S = AV / BV; + + var_data_int* data = var_data_alloc_G_INT(S); + + var_set(var, data, G_INT); + + return var; +} +var_cont* var_div(var_cont* A, var_cont* B) +{ + var_cont* rv; + + ASSERT(( A->type == B->type ), "Inconsistent Types\n"); + if (A->type == G_INT && B->type == G_INT) + { + rv = var_div_int(A, B); + } else + if (A->type == G_FLOAT && B->type == G_FLOAT) + { + rv = var_div_float(A, B); + } + + N_ASSERT(rv); + + return rv; +} diff --git a/src/vm/tests/bytecodes/looptest b/src/vm/tests/bytecodes/looptest Binary files differ