--- /dev/null
+#ifndef TEST_AST_MACROS_HDR
+#define TEST_AST_MACROS_HDR
+
+#if 0
+VAR(TYPE_FLOAT, i);
+VAR(TYPE_FLOAT, x);
+
+VAR(TYPE_FLOAT, f0);
+VAR(TYPE_FLOAT, f1);
+VAR(TYPE_FLOAT, f5);
+
+MKCONSTFLOAT(f0, 0.0);
+MKCONSTFLOAT(f1, 1.0);
+MKCONSTFLOAT(f5, 5.0);
+
+STATE(ASSIGN(STORE_F, i, f0));
+WHILE(BIN(LT, i, f5));
+STATE(ASSIGN(STORE_F, x, BIN(MUL_F, i, f5)));
+STATE(ASSIGN(STORE_F, i, BIN(ADD_F, i, f1)));
+ENDWHILE();
+#endif
+
+#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 MKGLOBAL(name) \
+assert(globals_add(name) >= 0)
+
+#define MKCONSTFLOAT(name, value) \
+do { \
+ name->isconst = true; \
+ name->constval.vfloat = value; \
+ 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, (a), (ast_expression*)(b))
+
+#define BIN(op, a, b) \
+(ast_expression*)ast_binary_new(ctx, INSTR_##op, (ast_expression*)(a), (ast_expression*)(b))
+
+#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 FUNCTION(name) \
+do { \
+ ast_function *func_##name; \
+ ast_block *my_funcblock; \
+ DEFVAR(var_##name); \
+ VAR(TYPE_FUNCTION, var_##name); \
+ MKGLOBAL(var_##name); \
+ func_##name = ast_function_new(ctx, #name, var_##name); \
+ 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
VECTOR_MAKE(ast_value*, globals);
VECTOR_MAKE(ast_function*, functions);
+#if 0
int main()
{
/* AST */
assert(!"finalize on function failed...");
}
+ /* dump */
+ ir_builder_dump(ir, printf);
+
+ /* 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;
+}
+#endif
+
+#include "ast-macros.h"
+
+int main()
+{
+ size_t i;
+
+ ir_builder *ir;
+
+ TESTVARS();
+
+ DEFVAR(vi);
+ DEFVAR(vx);
+ DEFVAR(f0);
+ DEFVAR(f1);
+ DEFVAR(f5);
+
+ TESTINIT();
+VAR(TYPE_FLOAT, f0);
+VAR(TYPE_FLOAT, f1);
+VAR(TYPE_FLOAT, f5);
+MKCONSTFLOAT(f0, 0.0);
+MKCONSTFLOAT(f1, 1.0);
+MKCONSTFLOAT(f5, 5.0);
+
+FUNCTION(main);
+
+VAR(TYPE_FLOAT, vi);
+VAR(TYPE_FLOAT, vx);
+
+MKLOCAL(vi);
+MKLOCAL(vx);
+
+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();
+
+ENDFUNCTION(main);
+
+ ir = ir_builder_new("ast_test");
+ assert(ir);
+
+ /* 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);