X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Fparser.y;h=9fe82df01a281f717e99f39fe5a55ed71d8ba20f;hp=c1f15f40289f1f37533f51316dd2be40bc143f39;hb=c719f3e6c6663f6640422d81c156231c84cdcbdf;hpb=0dc97f87cbbe47ef84501678f302404d042428b1 diff --git a/src/parser.y b/src/parser.y index c1f15f4..9fe82df 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,44 +1,50 @@ /* Asset Package Compiler */ -%code requires { + +%code requires { #include + #include "ir.h" + typedef struct class_state_t yycstate; + struct frame_spec_t { ir_facing d; int w, h; }; } - -%{ +%code provides { + yycstate* yycstate_new(void); + void yycstate_delete(yycstate*); +} +%code { #include #include #include #include #include "ir.h" - struct frame_spec_t { enum facing d; int w, h; }; + struct class_state_t { + ir_class *csp; + ir_class class_stack[]; + }; extern long sys_pagesize; extern int lexer(); static void yyerror(char const*); /* Stack-based class handler */ - static ir_class *class_stack, *csp; - static size_t class_stack_size; - static ir_class class_stack_init(void); - #define class_stack_pop() (*--csp) - static ir_class class_stack_push(ir_class); - - #define yylex lexer - #define yyclass (*csp) - #define yyclassld (ir_classld_from_class(yyclass)) -%} + #define CLASS_POP(CS) (*--(CS-csp)) + #define CLASS_PUSH(CS,CL) (*(CS->csp)++ = CL) + #define yyclass(CS) (*(CS->csp)) + #define yyclassld(CS) (ir_classld_from_class(yyclass(CS))) +} %define parse.error verbose %define lr.type ielr %define api.pure full %define api.push-pull push +%parse-param {yycstate* cs} %union { - long long ref; - int val; - enum facing face; - uint8_t* str; - ir_class class; - ir_set set; - ir_setld ld; - ir_setdata data; + long long ref; + int val; + ir_facing face; + uint8_t* str; + ir_class class; + ir_set set; + ir_setld ld; + ir_setdata data; struct frame_spec_t frame_spec; } /* Operators */ @@ -59,8 +65,6 @@ %type set_spec %type set_ld set_link %type frame_spec -/* Init */ -%initial-action { class_stack_init(); } %% /* Syntax Directed Translation Scheme of the APC grammar */ progn: @@ -75,9 +79,9 @@ class_list: ; class: - NAME CLOPEN { class_stack_push(ir_class_addchild(yyclass, $1)); } + NAME CLOPEN { CLASS_PUSH(cs,ir_class_addchild(yyclass, $1)); } progn - CLCLOSE { class_stack_pop(); } + CLCLOSE { CLASS_POP(cs); } ; statement_list: @@ -127,55 +131,24 @@ frame_spec: %% -#define ERR_ALLOC "memory allocation error\n" - -/* print to stderr */ static void yyerror ( char const *s ) { fprintf(stderr, "%s\n", s); } -/* Initialize the class stack - If the class_stack hasn't been allocated yet, allocates a page for pointers - to be stored in. Initializes class stack pointer, and inserts the root class - from IR - Returns the root class given by IR. -*/ -static -ir_class class_stack_init +yycstate* yycstate_new ( void ) -{ if (class_stack == NULL) - { class_stack_size = (size_t) sys_pagesize; - class_stack = (ir_class*) malloc(class_stack_size); - if (class_stack == NULL) - { yyerror(ERR_MEM); - exit(1); - } +{ yycstate* class_state; + class_state = (yycstate*) malloc((size_t) sys_pagesize); + if(class_state == NULL) + { yyerror(ERR_MEM); + exit(1); } - csp = class_stack; - return class_stack_push(ir_class_root()); + class_state->csp = &class_state->class_stack[0]; + CLASS_PUSH(class_state, ir_class_root()); + return class_state; } -/* Add a Class to the Stack - Allocated in page-sized chunks, potentially infinite depth is supported. - Returns the input class. -*/ -static -ir_class class_stack_push -#define class_size (sizeof(*class_stack)) -( ir_class class ) -{ size_t class_stack_len = csp - class_stack; - ir_class* new_class_stack; - if ((class_stack_len * class_size + class_size) > class_stack_size) - { class_stack_size += (size_t) sys_pagesize; - new_class_stack = (ir_class*) realloc(class_stack, class_stack_size); - if (new_class_stack == NULL) - { free(class_stack); //realloc failure does not free class_stack - yyerror("realloc " ERR_MEM); - exit(1); - } - class_stack = new_class_stack; - csp = class_stack + class_stack_len; - } - return (*csp++ = class); -} +void yycstate_delete +( yycstate* class_state ) +{ free(class_state); }