+++ /dev/null
-#ifndef TEST_AST_MACROS_HDR
-#define TEST_AST_MACROS_HDR
-
-#define TESTVARS() \
-ast_block *curblock; \
-lex_ctx ctx
-
-#define TESTINIT() \
-ctx.file = NULL; \
-ctx.line = 1;
-
-#define DEFVAR(name) \
-ast_value *name
-
-#define VAR(type, name) \
-name = ast_value_new(ctx, #name, type)
-
-#define VARnamed(type, name, varname) \
-name = ast_value_new(ctx, #varname, type)
-
-#define MKGLOBAL(name) \
-assert(globals_add(name) >= 0)
-
-#define FIELD(type, name) \
-name = ast_value_new(ctx, #name, TYPE_FIELD); \
-do { \
- ast_value *field_##name = ast_value_new(ctx, #name, type); \
- name->expression.next = (ast_expression*)field_##name; \
- MKFIELD(name); \
-} while (0)
-
-#define MKFIELD(name) \
-assert(fields_add(name) >= 0)
-
-#define MKCONSTFLOAT(name, value) \
-do { \
- name->isconst = true; \
- name->constval.vfloat = value; \
- MKGLOBAL(name); \
-} while(0)
-
-#define MKCONSTSTRING(name, value) \
-do { \
- name->isconst = true; \
- name->constval.vstring = util_strdup(value); \
- MKGLOBAL(name); \
-} while(0)
-
-#define MKCONSTVECTOR(name, valx, valy, valz) \
-do { \
- name->isconst = true; \
- name->constval.vvec.x = (valx); \
- name->constval.vvec.y = (valy); \
- name->constval.vvec.z = (valz); \
- MKGLOBAL(name); \
-} while(0)
-
-#define STATE(a) \
-do { \
- ast_expression *exp = (ast_expression*)(a); \
- assert(ast_block_exprs_add(curblock, exp)); \
-} while(0)
-
-#define ASSIGN(op, a, b) \
-(ast_expression*)ast_store_new(ctx, INSTR_##op, (ast_expression*)(a), (ast_expression*)(b))
-
-#define BIN(op, a, b) \
-(ast_expression*)ast_binary_new(ctx, INSTR_##op, (ast_expression*)(a), (ast_expression*)(b))
-
-#define ENTFIELD(a, b) \
-(ast_expression*)ast_entfield_new(ctx, (ast_expression*)(a), (ast_expression*)(b))
-
-#define VECMEM(vec, mem) \
-(ast_expression*)ast_member_new(ctx, (ast_expression*)(vec), (mem))
-
-#define CALL(what) \
-do { \
- ast_call *call = ast_call_new(ctx, (ast_expression*)what); \
-
-#define CALLPARAM(x) \
- assert(ast_call_params_add(call, (ast_expression*)x));
-
-#define ENDCALL() \
- STATE(call); \
-} while(0)
-
-#define ENDCALLWITH(as, where) \
- { \
- ast_expression *as = (ast_expression*)call; \
- where; \
- } \
-} while(0)
-
-#define WHILE(cond) \
-do { \
- ast_expression *wh_cond = (ast_expression*)(cond); \
- ast_block *wh_body = ast_block_new(ctx); \
- ast_block *oldcur = curblock; \
- ast_loop *loop; \
- curblock = wh_body;
-
-#define ENDWHILE() \
- curblock = oldcur; \
- loop = ast_loop_new(ctx, NULL, (ast_expression*)wh_cond, \
- NULL, NULL, (ast_expression*)wh_body); \
- assert(loop); \
- STATE(loop); \
-} while(0)
-
-#define BUILTIN(name, outtype, number) \
-do { \
- ast_function *func_##name; \
- ast_value *thisfuncval; \
- ast_function *thisfunc; \
- DEFVAR(return_##name); \
- VARnamed(TYPE_FUNCTION, name, name); \
- VARnamed(outtype, return_##name, "#returntype"); \
- name->expression.next = (ast_expression*)return_##name; \
- MKGLOBAL(name); \
- func_##name = ast_function_new(ctx, #name, name); \
- thisfunc = func_##name; \
- (void)thisfunc; \
- thisfuncval = name; \
- (void)thisfuncval; \
- assert(functions_add(func_##name) >= 0); \
- func_##name->builtin = number;
-
-#define ENDBUILTIN() } while(0)
-
-#define PARAM(ptype, name) \
-do { \
- DEFVAR(parm); \
- VARnamed(ptype, parm, name); \
- assert(ast_value_params_add(thisfuncval, parm)); \
-} while(0)
-
-#define FUNCTION(name, outtype) \
-do { \
- ast_function *thisfunc; \
- ast_function *func_##name; \
- ast_block *my_funcblock; \
- DEFVAR(var_##name); \
- DEFVAR(return_##name); \
- VARnamed(TYPE_FUNCTION, var_##name, name); \
- VARnamed(outtype, return_##name, "#returntype"); \
- var_##name->expression.next = (ast_expression*)return_##name; \
- MKGLOBAL(var_##name); \
- func_##name = ast_function_new(ctx, #name, var_##name); \
- thisfunc = func_##name; \
- (void)thisfunc; \
- assert(functions_add(func_##name) >= 0); \
- my_funcblock = ast_block_new(ctx); \
- assert(my_funcblock); \
- assert(ast_function_blocks_add(func_##name, my_funcblock)); \
- curblock = my_funcblock;
-
-#define MKLOCAL(var) \
- assert(ast_block_locals_add(curblock, var))
-
-#define ENDFUNCTION(name) \
-} while(0)
-
-#endif
+++ /dev/null
-#include "gmqcc.h"
-#include "ast.h"
-
-/* NOTE: it's a test - I'll abort() on epic-failure */
-
-#ifdef assert
-# undef assert
-#endif
-/* (note: 'do {} while(0)' forces the need for a semicolon after assert() */
-#define assert(x) do { if ( !(x) ) { printf("Assertion failed: %s\n", #x); abort(); } } while(0)
-
-VECTOR_MAKE(ast_value*, globals);
-VECTOR_MAKE(ast_value*, fields);
-VECTOR_MAKE(ast_function*, functions);
-
-uint32_t opts_flags[1 + (COUNT_FLAGS / 32)];
-uint32_t opts_warn [1 + (COUNT_WARNINGS / 32)];
-
-uint32_t opts_O = 1;
-const char *opts_output = "progs.dat";
-int opts_standard = COMPILER_GMQCC;
-bool opts_debug = false;
-bool opts_memchk = false;
-bool opts_werror = false;
-
-#include "ast-macros.h"
-
-int main()
-{
- size_t i;
-
- ir_builder *ir;
-
- TESTVARS();
-
- DEFVAR(vi);
- DEFVAR(vx);
- DEFVAR(f0);
- DEFVAR(f1);
- DEFVAR(f5);
- DEFVAR(cv3x4x5);
- DEFVAR(cv1x1x1);
- DEFVAR(sHello);
- DEFVAR(sNL);
- DEFVAR(print);
- DEFVAR(ftos);
- DEFVAR(spawn);
-
- DEFVAR(mema);
- DEFVAR(memb);
- DEFVAR(memv);
- DEFVAR(pawn);
-
- /* opts_debug = true; */
-
-BUILTIN(print, TYPE_VOID, -1);
-PARAM(TYPE_STRING, text);
-ENDBUILTIN();
-
-BUILTIN(ftos, TYPE_STRING, -2);
-PARAM(TYPE_FLOAT, value);
-ENDBUILTIN();
-
-BUILTIN(spawn, TYPE_ENTITY, -3);
-ENDBUILTIN();
-
- TESTINIT();
-VAR(TYPE_FLOAT, f0);
-VAR(TYPE_FLOAT, f1);
-VAR(TYPE_FLOAT, f5);
-VAR(TYPE_STRING, sHello);
-VAR(TYPE_STRING, sNL);
-VAR(TYPE_VECTOR, cv3x4x5);
-VAR(TYPE_VECTOR, cv1x1x1);
-
-FIELD(TYPE_FLOAT, mema);
-FIELD(TYPE_FLOAT, memb);
-FIELD(TYPE_VECTOR, memv);
-
-MKCONSTFLOAT(f0, 0.0);
-MKCONSTFLOAT(f1, 1.0);
-MKCONSTFLOAT(f5, 5.0);
-MKCONSTSTRING(sHello, "Hello, World\n");
-MKCONSTSTRING(sNL, "\n");
-MKCONSTVECTOR(cv3x4x5, 3, 4, 5);
-MKCONSTVECTOR(cv1x1x1, 1, 1, 1);
-
-FUNCTION(foo, TYPE_VOID);
-ENDFUNCTION(foo);
-
-#define PRINTNL() do { CALL(print) CALLPARAM(sNL) ENDCALL(); } while(0)
-
-FUNCTION(main, TYPE_VOID);
-
- VAR(TYPE_FLOAT, vi);
- VAR(TYPE_FLOAT, vx);
- VAR(TYPE_ENTITY, pawn);
-
- MKLOCAL(vi);
- MKLOCAL(vx);
- MKLOCAL(pawn);
-
- STATE(ASSIGN(STORE_F, vi, f0));
- WHILE(BIN(LT, vi, f5));
- STATE(ASSIGN(STORE_F, vx, BIN(MUL_F, vi, f5)));
- STATE(ASSIGN(STORE_F, vi, BIN(ADD_F, vi, f1)));
- ENDWHILE();
-
- CALL(print)
- CALLPARAM(sHello)
- ENDCALL();
-
- CALL(spawn)
- ENDCALLWITH(newent, STATE(ASSIGN(STORE_ENT, pawn, newent)));
-
- STATE(ASSIGN(STOREP_F, ENTFIELD(pawn, mema), f5));
- STATE(ASSIGN(STOREP_F, ENTFIELD(pawn, memb), f1));
- STATE(ASSIGN(STOREP_V, ENTFIELD(pawn, memv), cv3x4x5));
- CALL(ftos)
- CALLPARAM(ENTFIELD(pawn, mema))
- ENDCALLWITH(output,
- CALL(print)
- CALLPARAM(output)
- CALLPARAM(sNL)
- ENDCALL();
- );
- CALL(ftos)
- CALLPARAM(ENTFIELD(pawn, memb))
- ENDCALLWITH(output,
- CALL(print)
- CALLPARAM(output)
- CALLPARAM(sNL)
- ENDCALL();
- );
- CALL(ftos)
- CALLPARAM(ENTFIELD(pawn, VECMEM(memv, 2)))
- ENDCALLWITH(output,
- CALL(print)
- CALLPARAM(output)
- CALLPARAM(sNL)
- ENDCALL();
- );
-
-ENDFUNCTION(main);
-
- ir = ir_builder_new("ast_test");
- assert(ir);
-
- /* gen fields */
- for (i = 0; i < fields_elements; ++i) {
- if (!ast_global_codegen(fields_data[i], ir)) {
- assert(!"failed to generate field");
- }
- }
- /* gen globals */
- for (i = 0; i < globals_elements; ++i) {
- if (!ast_global_codegen(globals_data[i], ir)) {
- assert(!"failed to generate global");
- }
- }
-
- /* gen functions */
- for (i = 0; i < functions_elements; ++i) {
- if (!ast_function_codegen(functions_data[i], ir)) {
- assert(!"failed to generate function");
- }
- if (!ir_function_finalize(functions_data[i]->ir_func))
- assert(!"finalize on function failed...");
- }
-
-
- /* dump */
- ir_builder_dump(ir, printf);
-
- /* Now create a file */
- if (!ir_builder_generate(ir, "test_ast.dat"))
- printf("*** failed to generate code\n");
-
- /* ir cleanup */
- ir_builder_delete(ir);
-
- /* cleanup */
- /* Functions must be deleted FIRST since their expressions
- * reference global variables.
- */
- for (i = 0; i < functions_elements; ++i) {
- ast_function_delete(functions_data[i]);
- }
- if (functions_data)
- mem_d(functions_data);
-
- /* We must delete not only globals, but also the functions'
- * ast_values (their type and name), that's why we added them to the globals vector.
- */
- for (i = 0; i < globals_elements; ++i) {
- ast_value_delete(globals_data[i]);
- }
- if (globals_data)
- mem_d(globals_data);
- return 0;
-}
+++ /dev/null
-#include "gmqcc.h"
-#include "ir.h"
-
-#ifdef assert
-# undef assert
-#endif
-/* (note: 'do {} while(0)' forces the need for a semicolon after assert() */
-#define assert(x) do { if ( !(x) ) { printf("Assertion failed: %s\n", #x); abort(); } } while(0)
-
-int main()
-{
- int lf;
-
- ir_builder *b = ir_builder_new("test");
- ir_value *va = ir_builder_create_global(b, "a", TYPE_FLOAT);
- ir_value *v3 = ir_builder_create_global(b, "const_f_3", TYPE_FLOAT);
- ir_value *vb = ir_builder_create_global(b, "b", TYPE_FLOAT);
- ir_value *vc = ir_builder_create_global(b, "c", TYPE_FLOAT);
- ir_value *vd = ir_builder_create_global(b, "d", TYPE_FLOAT);
-
- ir_value *life1 = ir_builder_create_global(b, "life1", TYPE_FLOAT);
- ir_value *life2 = ir_builder_create_global(b, "life2", TYPE_FLOAT);
- ir_value *life3 = ir_builder_create_global(b, "life3", TYPE_FLOAT);
-
- ir_function *fmain = NULL;
- ir_value *la = NULL;
- ir_block *bmain = NULL;
- ir_block *blt = NULL;
- ir_block *bge = NULL;
- ir_block *bend = NULL;
- ir_value *sum = NULL;
- ir_value *prd = NULL;
- ir_value *less = NULL;
- ir_value *x1 = NULL;
- ir_value *vig = NULL;
- ir_value *x2 = NULL;
- ir_instr *retphi = NULL;
- ir_value *retval = NULL;
-
- assert(ir_value_set_float(v3, 3.0f) );
- assert(ir_value_set_float(vb, 4.0f) );
- assert(ir_value_set_float(vc, 10.0f) );
- assert(ir_value_set_float(vd, 20.0f) );
-
- fmain = ir_builder_create_function(b, "main");
- assert(fmain);
-
- la = ir_function_create_local(fmain, "loc1", TYPE_FLOAT);
- assert(la);
-
- assert( bmain = ir_function_create_block(fmain, "top") );
- assert( blt = ir_function_create_block(fmain, "less") );
- assert( bge = ir_function_create_block(fmain, "greaterequal") );
- assert( bend = ir_function_create_block(fmain, "end") );
-
- assert(ir_block_create_store_op(bmain, INSTR_STORE_F, va, v3));
- assert( sum = ir_block_create_add(bmain, "%sum", va, vb) );
- assert( prd = ir_block_create_mul(bmain, "%mul", sum, vc) );
- assert( less = ir_block_create_binop(bmain, "%less", INSTR_LT, prd, vd) );
-
- assert(ir_block_create_if(bmain, less, blt, bge));
-
- x1 = ir_block_create_binop(blt, "%x1", INSTR_ADD_F, sum, v3);
- assert(x1);
- assert(ir_block_create_goto(blt, bend));
-
- vig = ir_block_create_binop(bge, "%ignore", INSTR_ADD_F, va, vb);
- assert(vig);
- assert(ir_block_create_store_op(bge, INSTR_STORE_F, la, vig));
- x2 = ir_block_create_binop(bge, "%x2", INSTR_ADD_F, sum, v3);
- assert(x2);
- assert(ir_block_create_goto(bge, bend));
-
- retphi = ir_block_create_phi(bend, "%retval", TYPE_FLOAT);
- assert(retphi);
- assert(ir_phi_add(retphi, blt, x1));
- assert(ir_phi_add(retphi, bge, x2));
- retval = ir_phi_value(retphi);
- assert(retval);
- assert(ir_block_create_return(bend, retval));
-
- /*
- printf("%i should be 1\n", ir_value_life_merge(va, 31));
- printf("%i should be 1\n", ir_value_life_merge(va, 33));
- printf("%i should be 0\n", ir_value_life_merge(va, 33));
- printf("%i should be 1\n", ir_value_life_merge(va, 1));
- printf("%i should be 1\n", ir_value_life_merge(va, 2));
- printf("%i should be 1\n", ir_value_life_merge(va, 20));
- printf("%i should be 1\n", ir_value_life_merge(va, 21));
- printf("%i should be 1\n", ir_value_life_merge(va, 8));
- printf("%i should be 1\n", ir_value_life_merge(va, 9));
- printf("%i should be 1\n", ir_value_life_merge(va, 3));
- printf("%i should be 0\n", ir_value_life_merge(va, 9));
- printf("%i should be 1\n", ir_value_life_merge(va, 17));
- printf("%i should be 1\n", ir_value_life_merge(va, 18));
- printf("%i should be 1\n", ir_value_life_merge(va, 19));
- printf("%i should be 0\n", ir_value_life_merge(va, 19));
- ir_value_dump_life(va, printf);
- printf("%i should be 1\n", ir_value_life_merge(va, 10));
- printf("%i should be 1\n", ir_value_life_merge(va, 9));
- printf("%i should be 0\n", ir_value_life_merge(va, 10));
- printf("%i should be 0\n", ir_value_life_merge(va, 10));
- ir_value_dump_life(va, printf);
- */
-
- ir_builder_dump(b, printf);
- assert(ir_function_finalize(fmain));
- ir_builder_dump(b, printf);
-
- ir_value_dump_life(sum, printf);
- ir_value_dump_life(prd, printf);
- ir_value_dump_life(less, printf);
- ir_value_dump_life(x1, printf);
- ir_value_dump_life(x2, printf);
- ir_value_dump_life(retval, printf);
- ir_value_dump_life(vig, printf);
- ir_value_dump_life(la, printf);
-
- ir_value_life_merge_into(retval, vig);
- ir_value_dump_life(retval, printf);
- ir_value_life_merge(x1, 12);
- ir_value_life_merge(x1, 13);
- ir_value_life_merge(x1, 14);
- ir_value_life_merge_into(retval, x1);
- ir_value_dump_life(retval, printf);
- ir_value_life_merge(x1, 20);
- ir_value_life_merge(x1, 21);
- ir_value_life_merge(x1, 22);
- ir_value_life_merge_into(retval, x1);
- ir_value_dump_life(retval, printf);
- ir_value_life_merge(x2, 1);
- ir_value_life_merge(x2, 2);
- ir_value_life_merge_into(retval, x2);
- ir_value_dump_life(retval, printf);
- for (lf = 4; lf <= 15; ++lf)
- ir_value_life_merge(life1, lf);
- ir_value_life_merge_into(retval, life1);
- ir_value_dump_life(retval, printf);
- for (lf = 17; lf <= 18; ++lf)
- ir_value_life_merge(life2, lf);
- ir_value_life_merge_into(retval, life2);
- ir_value_dump_life(retval, printf);
- for (lf = 2; lf <= 29; ++lf)
- ir_value_life_merge(life3, lf);
- ir_value_life_merge_into(retval, life3);
- ir_value_dump_life(retval, printf);
-
- ir_builder_delete(b);
- return 0;
-}