From: Jordan Date: Fri, 14 Oct 2016 03:04:19 +0000 (-0700) Subject: no longer hidden X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fwebcc.git;a=commitdiff_plain;h=e90a923eb02cb13d681839e839f07018f170d461 no longer hidden --- diff --git a/org/data/2d/ec5876-7b81-4b9c-97fe-03b152fa276a/scanner.c b/org/data/2d/ec5876-7b81-4b9c-97fe-03b152fa276a/scanner.c new file mode 100755 index 0000000..f982cf2 --- /dev/null +++ b/org/data/2d/ec5876-7b81-4b9c-97fe-03b152fa276a/scanner.c @@ -0,0 +1,210 @@ +/*!@file + \brief APC Directory Scanner + \details This hand-written parser/scanner traverses a directory tree and + tokenizes elements of the structure which correspond to APC grammar. + The parser is implemented as a 2D stack which populates a list of + child directories at each depth, handling only the leaf nodes + (regular files) of the directory open at the current depth to + conserve memory and speed up traversal. + The scanner works with the lexer to lexically analyze text, and + assumes the existence of an external 'lex' function + \author Jordan Lavatai + \date Aug 2016 + ----------------------------------------------------------------------------*/ +/* Standard */ +#include //print +#include //errno +/* Posix */ +#include //warnx +#include //exit +#include //chdir +#include //opendir + +#include "parser.tab.h" +/* Public */ +int scanner_init(void); +void scanner_quit(void); +int scanner(void); +/* Private */ +#ifndef DL_STACKSIZE +#define DL_STACKSIZE 64 +#endif +#ifndef DL_CD_STACKSIZE +#define DL_CD_STACKSIZE DL_STACKSIZE //square tree +#endif +extern //lexer.c +int lexer_lex(const char*); +extern //lexer.c +void lexer_pushtok(int, int); +static +int dredge_current_depth(void); +extern //lexer.c +struct dirent* lexer_direntpa[], **lexer_direntpp; +extern //SRC_DIR/bin/tools/apc.c +const char* cargs['Z']; + +struct dirlist +{ DIR* dirp; + struct dirent* child_directory_stack[DL_CD_STACKSIZE],** cds; +} directory_list_stack[DL_STACKSIZE + 1],* dls; //+1 for the root dir + +/* Directory Listing Stack + FILO Stack for keeping an open DIR* at each directory depth for treewalk. + This stack is depth-safe, checking its depth during push operations, but not + during pop operations, to ensure the thread doesn't open too many files at + once (512 in c runtime), or traverse too far through symbolic links. + A directory listing includes a DIR* and all DIR-typed entity in the directory + as recognized by dirent, populated externally (and optionally). + This stack behaves abnormally by incrementing its PUSH operation prior to + evaluation, and the POP operations after evaluation. This behavior allows + the 'DL_CURDEPTH' operation to map to the current element in the 'dl_stack' + array, and it is always treated as the "current depth". This also allows us + to init the root directory to 'directory_list_stack'[0] and pop it in a safe + and explicit manner. +*/ +#define DL_STACK (directory_list_stack) +#define DL_STACKP (dls) +#define DL_CD_STACK ((*DL_STACKP).child_directory_stack) +#define DL_CD_STACKP ((*DL_STACKP).cds) +#define DL_CURDIR() ((*DL_STACKP).dirp) +#define DL_LEN() (DL_STACKP - DL_STACK) +#define DL_CD_LEN() (DL_CD_STACKP - DL_CD_STACK) +#define DL_INIT() (DL_STACKP = DL_STACK) +#define DL_CD_INIT() (DL_CD_STACKP = DL_CD_STACK) +#define DL_POP() ((*DL_STACKP--).dirp) +#define DL_CD_POP() (*--DL_CD_STACKP) +#define DL_PUSH(D) ((*++DL_STACKP).dirp = D) +#define DL_CD_PUSH(E) (*DL_CD_STACKP++ = E) + + +/* Initializer + Initializer expects a function pointer to its lexical analysis function. + Sets up stack pointers and returns boolean true if 'opendir' encounters an + error, or if dredge_current_depth returns boolean true. +*/ +int scanner_init +#define CWDSTR "./" +#define ROOTDIR (cargs['d'] ? cargs['d'] : CWDSTR) +() +{ DL_INIT(); + DL_STACK[0].dirp = opendir(ROOTDIR); + printf("Root dir %s\n",ROOTDIR); + return !chdir(ROOTDIR) && (DL_STACK[0].dirp == NULL || dredge_current_depth() == -1); +} + +/* Quit */ +void scanner_quit +() +{ if (DL_CURDIR()) + closedir(DL_CURDIR()); +} + +/* Scanner + The main driver of the scanner will advance the current treewalk state and + tokenize tree-based push/pop operations. It will call 'lexer_lex' to + tokenize directory names prior to making a push operation. safe checking for + all returns from the filesystem handler will exit on serious system errors. + + after pushing a new directory to the directory list, the scanner will dredge + the directory and alphabetically sort all file entries into the lexer's file + array, while placing all subdirectory entries in the current depth's child + directory stack to be scanned later. + + Returns the number of elements added to the lexer's file array, or -1 on + error +*/ +int scanner +#define $($)#$ //stringifier +#define ERR_CHILD "Fatal: Maximum of " $(DL_CD_STACKSIZE) \ + " child directories exceeded for directory at depth %i\n" \ + ,DL_LEN() +#define ERR_DEPTH "Fatal: Maximum directory depth of " $(DL_STACKSIZE) \ + " exceeded during directory scan\n" +#define ERR_DL "Fatal: Directory List Stack Corruption %x\n", DL_LEN() +#define TOK_CLOPEN 0x55, 1 //TODO +#define TOK_CLCLOSE 0x56, 1 //TODO +() +{ struct dirent* direntp; + struct DIR* DIRp; + parse: + if (DL_CD_LEN() >= DL_CD_STACKSIZE)//fail if maxchildren exceeded + { fprintf(stderr, ERR_CHILD); + goto fail; + } + if (DL_CD_LEN() > 0) //There are entities to process + { if ((direntp = DL_CD_POP()) == NULL)//If the dirent is null, the library + goto libfail; //function in dirent has failed + lexer_lex(direntp->d_name); //lex the directory name + if (DL_LEN() >= DL_STACKSIZE) //fail if maxdepth exceeded + { fprintf(stderr, ERR_DEPTH); + goto fail; + } + if (chdir(direntp->d_name)) //move into the new directory + goto libfail; + DL_PUSH(opendir(CWDSTR)); + if (DL_CURDIR() == NULL) //open the cwd + goto libfail; + lexer_pushtok(TOK_CLOPEN); //Push "Open Directory" token + return dredge_current_depth(); //Filter and sort the current depth + } + else if (DL_LEN() >= 0) //Any dirs left? (Including root) + { if (closedir(DL_POP())) //close the directory we just left + goto libfail; + if (DL_LEN() == -1) //If we just popped root, + return 0; //we're done + lexer_pushtok(TOK_CLCLOSE); //Else push "Close Directory" token, + if (!chdir("..")) //move up a directory and + goto parse; //start over + } + fprintf(stderr, ERR_DL); + libfail: + perror("parsedir"); + fail: + exit(EXIT_FAILURE); +} + +/* Directory Entity Sort and Filter (Dredge) + This filter removes all unhandled file types, and places any 'DT_DIR' type + files in the current Directory List's directory stack. Upon finishing, + the 'CE_STACK' is sorted alphabetically, and the current 'DL_CD_STACK' is + populated. Prints warnings for unhandled files. + + Returns -1 if 'readdir' encounters an error, otherwise returns the number of + directory entries sent to the external 'lexer_direntpa' array. +*/ +typedef +int (*qcomp)(const void*, const void*); +static inline +int dredge_current_depth +#define READDIR_ERROR (-1) +#define READDIR_DONE (0) +#define DPS_LEN() (lexer_direntpp - lexer_direntpa) +#define DPS_PUSH(E) (*lexer_direntpp++ = E) +() +{ struct dirent** direntpp = lexer_direntpa; + DIR* cwd = DL_CURDIR(); + struct dirent* direntp; + DL_CD_INIT(); + scan_next: + if ((direntp = readdir(cwd)) != NULL) + { switch (direntp->d_type) + { case DT_REG: + DPS_PUSH(direntp); + goto scan_next; + case DT_DIR: + if (*(direntp->d_name) == '.') //skip hidden files and relative dirs + goto scan_next; + DL_CD_PUSH(direntp); + goto scan_next; + case DT_UNKNOWN: + warnx("unknown file %s: ignoring", direntp->d_name); + default: + goto scan_next; + } + } + if (errno) + return -1; + qsort(lexer_direntpa, DPS_LEN(), sizeof direntp, (qcomp)alphasort); + return DPS_LEN(); +} + diff --git a/org/data/fa/f3ff67-f8e9-41fe-9a32-2ced4bbf5b99/lexer.c b/org/data/fa/f3ff67-f8e9-41fe-9a32-2ced4bbf5b99/lexer.c new file mode 100755 index 0000000..2252a37 --- /dev/null +++ b/org/data/fa/f3ff67-f8e9-41fe-9a32-2ced4bbf5b99/lexer.c @@ -0,0 +1,180 @@ +/*!@file + \brief lexical analyzer implementation for APC + \details The lexer manages two FIFO stacks. One for maintaining tokens, the + other for maintaining a list of files to be scanned. During + execution, the lexer will return a token from its token queue if any + are present. If not, the lexer will will pop an element from its + file queue to 'scanner' to be tokenized. If the file queue is empty, + the lexer will instead call 'parsedir' to traverse the directory tree + and tokenize the results. If 'parsedir' does not generate any new + tokens, we are done. + \author Jordan Lavatai + \date Aug 2016 + ----------------------------------------------------------------------------*/ +/* Standard */ +#include +#include +#include +/* Posix */ +#include +#include +#include +/* Local */ +#include "parser.tab.h" +#ifndef DE_STACKSIZE +#define DE_STACKSIZE 1024 +#endif +#ifndef TK_STACKSIZE +#define TK_STACKSIZE 1024 +#endif +/* Public */ +int lexer_init(void); +int lexer(void); +int lexer_lexfile(const char*); +void lexer_pushtok(int, YYSTYPE); +extern //lexer_lex.rl +int lexer_lex(const char*); +struct dirent* lexer_direntpa[DE_STACKSIZE], **lexer_direntpp; +/* Private */ +extern //scanner.c +int scanner_init(void); +extern //scanner.c +int scanner(void); +static inline +int dredge_current_depth(void); +extern //bison +YYSTYPE yylval; +static +struct tok +{ YYSTYPE lval; //token val + int tok_t; //token type +} token_stack[TK_STACKSIZE]; +static +union tokp +{ int* tpt; //token pointer type + struct tok* tok; + YYSTYPE* tvp; //token value pointer +} tks, tkx; + +/* Directory Entity Array/Stack + Simple array for keeping track of dirents yet to be processed by the scanner. + If this list is empty and there are no tokens, the lexer is done. + This array is populated by the scanner as an array, and popped locally by the + lexer as a stack. +*/ +#define DE_STACK (lexer_direntpa) +#define DE_STACKP (lexer_direntpp) +#define DE_LEN() (DE_STACKP - DE_STACK) +#define DE_INIT() (DE_STACKP = DE_STACK) +#define DE_POP() (*--DE_STACKP) + +/* Token Stack + This is a FIFO stack whose pointers are a union of either a pointer to an + integer, or a pointer to two integers (a struct tok). This way, integers may + be added or removed from the stack either singularly (IPUSH/IPOP), or as a + full token of two integers (PUSH/POP). + An alignment error will occur if IPOP or IPUSH are used a non-even number of + times in a sequence! +*/ +#define TK_STACK (token_stack) +#define TK_STACKP (tks.tok) +#define TK_STACKPI (tks.tpt) +#define TK_STACKPL (tks.tvp) +#define TK_STACKX (tkx.tok) +#define TK_STACKXI (tkx.tpt) +#define TK_LEN() (TK_STACKX - TK_STACKP) +#define TK_INIT() (TK_STACKP = TK_STACKX = TK_STACK) +#define TK_POP() (*TK_STACKP++) +#define TK_POPI() (*TK_STACKPI++); +#define TK_POPL() (*TK_STACKPL++); +#define TK_PUSH(T,L) (*TK_STACKX++ = (struct tok){L,T}) + +/* Initializer + The initializer returns boolean true if an error occurs, which may be handled with standard errno. +*/ +int lexer_init +() +{ TK_INIT(); + DE_INIT(); + return scanner_init(); +} + +/* Lexer + If the token buffer is empty, 'lexer' will initialize the token buffer and + call 'lexer_scandir'. If SCAN_ERROR is returned, an error is printed + before sending a null return to bison. If 0 tokens are generated, the error + printing is skipped. In all other cases, 'yylval' is set, and the token's + integer representation is returned. +*/ +int lexer +#define $($)#$ +#define SCAN_ERROR -1 +#define TK_EMPTY (TK_STACKP == TK_STACKX) +#define FAIL(...) \ + do { \ + fprintf(stderr,__VA_ARGS__); \ + goto done; \ + } while (0) +() +{start: + while (DE_LEN() > 0) //lex any directory entries in our stack + if (lexer_lexfile(DE_POP()->d_name) == 0) + FAIL("Lexer failed to tokenize [%s]\n",(*DE_STACKP)->d_name); + if (TK_EMPTY) //if there are no tokens, + { TK_INIT(); //initialize the token stack back to 0 + switch (scanner()) + { case SCAN_ERROR: //if an error occurred, + FAIL("Scanner error\n"); + case 0: //if the the scanner finds no dirents, + goto done; //then we are done + default: //if we found some elements to scan, + goto start; //start over and lex them + } + } + yylval = TK_POPL(); + return TK_POPI(); + done: + yylval.val = 0; + return 0; +} + + +/* Token Receiver + This receiver takes a struct tok and pushes it to the FIFO stack. +*/ +void lexer_pushtok +#define $($)#$ //stringifier +#define ERR_TK "Fatal: Generated over " $(TK_STACKSIZE) " tokens in one pass." +( int tok, YYSTYPE lval ) +{ if (TK_LEN() >= TK_STACKSIZE) + { fprintf(stderr, ERR_TK); + exit(EXIT_FAILURE); + } + TK_PUSH(tok, lval); + printf("Pushed Token %i | %i\n", TK_STACK[TK_LEN() - 1].tok_t, TK_STACK[TK_LEN() - 1].lval.val); +} + +/* Lexical analysis of a file + Strips a filename to its base name, then sends it to lexer_lex +*/ +int lexer_lexfile +#define MAX_FNAME 2048 +#define HIDDEN_WARNING "%s is hidden and will not be parsed!\n", filename +( const char *filename +) +{ static char fname[MAX_FNAME]; + char *last_period = NULL, *iter; + + if (*filename == '.') + { fprintf (stderr, HIDDEN_WARNING); + return 0; + } + strncpy(fname,filename,MAX_FNAME); + last_period = NULL; + for (iter = fname; *iter; iter++) + if (*iter == '.') + last_period = iter; + if (last_period) + *last_period = '\0'; + return lexer_lex(fname); +} diff --git a/org/data/fa/f3ff67-f8e9-41fe-9a32-2ced4bbf5b99/lexer_lex.rl b/org/data/fa/f3ff67-f8e9-41fe-9a32-2ced4bbf5b99/lexer_lex.rl new file mode 100755 index 0000000..0224bb8 --- /dev/null +++ b/org/data/fa/f3ff67-f8e9-41fe-9a32-2ced4bbf5b99/lexer_lex.rl @@ -0,0 +1,115 @@ +/* Ragel State Machine for tokenizing text */ +#include +#include +#include + +extern void lexer_pushtok(int, YYSTYPE); + +int lexer_lex(const char*); +int ipow(int, int); +int ttov(const char* str, int); +uint64_t ttor(const char* str, int); +char* ttos(const char* str, int); + + +#define MAX_TOK_LEN 64 +#define MAX_TOKENS 16 +#define MAX_STR_SIZE (MAX_TOK_LEN * MAX_TOKENS) +#define $($)#$ +#define PUSHTOK(TOK,LFUNC,UTYPE) \ + do { \ + printf("PUSHTOK(" $(TOK) $(LFUNC) $(UTYPE) ")\n"); \ + tok_t = TOK; \ + yylval.UTYPE = LFUNC(ts, p-ts); \ + lexer_pushtok(tok_t, yylval); \ + ++ntok; \ + } while (0) + +%%{ + machine token_matcher; + + # set up yylval and tok_t to be pushed to stack + action set_ref { PUSHTOK(REF, ttor, ref); } + action set_val { PUSHTOK(NUM, ttov, val); } + action set_name { PUSHTOK(NAME, ttos, str); } + action set_ts { ts = p; } + action lex_error {printf("input error: character %c in filename %s is invalid\n", fc, str);} + + # instantiate machines for each possible token + ref = '0x' xdigit+ %set_ref; + val = digit+ %set_val; + name = alpha+ %set_name; + tok = ref | val | name; + segment = (tok . '_') %set_ts; + + main := segment* . tok $lerr(lex_error); +}%% + + +%%write data; + +/* Scan filename and push the its tokens + onto the stack */ +int lexer_lex (const char* str) +{ + const char *p, *pe, *ts, *eof; + int cs, tok_t, ntok = 0; + printf ("Lexing: %s\n",str); + p = ts = str; + pe = p + strlen(str); + %%write init; + %%write exec; + printf ("Lexed %i tokens\n",ntok); + return ntok; +} + +int ipow(int base, int exp) +{ + int result = 1; + while (exp) + { + if (exp & 1) + result = result * base; + exp = exp >> 1; + base *= base; + } + + return result; +} + +/* Token to Value */ +int ttov(const char* str, int len) +{ + int i, val = 0; + + for (i = 0; i < len; i++) + { + val += ((str[len - (i + 1)] - '0') * ipow(10,i)); + } + + return val; +} + +uint64_t ttor(const char* str, int len) +{ + int i; + uint64_t num = 0; + + for (i = 0; i < len; i++) + { + num += ((str[len - (i + 1)] - '0') * ipow(10,i)); + } + + return num; +} + +char* ttos(const char* str, int len) +{ + int i; + char token_buf[MAX_TOK_LEN]; + + memmove(token_buf, str, len); + token_buf[len+1] = '\0'; + + return strdup(token_buf); +} diff --git a/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/ir.c b/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/ir.c new file mode 100755 index 0000000..421f6e5 --- /dev/null +++ b/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/ir.c @@ -0,0 +1,465 @@ +/*!@file + \brief IR Memory Implementation + \details Intermediary memory management + \author Jordan Lavatai + \date Aug 2016 + ----------------------------------------------------------------------------*/ +#include +#include +#include //uint64_t +#include //memmove +#include //malloc +#include + + + +/* functions needed from irmem.c */ +extern +void +ir_init(void); + +extern +struct cdat* +alloc_cdat(void); + +extern +struct odat* +alloc_odat(void); + +extern +void +alloc_vdat(void); + +extern +struct link* +alloc_link(void); + +extern +struct ref* +alloc_ref(void); + +extern +struct cdat* +curr_cdat(void); + +extern +struct odat* +curr_odat(void); + +extern +struct vdat* +curr_vdat(void); + +extern +struct set* +curr_set(void); + +extern +struct ref* +curr_ref(void); + +extern +struct quad* +curr_quad(void); + +extern +struct model* +curr_model(void); + +/* struct definitions needed from irmem.c */ +extern int num_cdats; +extern struct cdat** cdat_stackp; +extern struct odat* curr_set_odatp; +extern uint64_t ss_ref_id; + +extern int num_vdats; +/* Dynamically allocate memory for a class data structure, + or cdat, after a class has been identified in a grammar. + We also create a stack of class pointers so that + we can access the cdat during processing of that + cdats sets and elements, a requirement because the + nature of recursive classes prevents us from accessing + the cdat based on the previous index into cdat_buf, + which is a list of all allocated cdats*/ +void +push_cdat +( char* name +) +{ + struct cdat* curr_cdatp; + + curr_cdatp = alloc_cdat(); + + memmove(curr_cdatp->name, name, 32); + curr_cdatp->idx = num_cdats; + + /* Set the cdat as a subclass of the previous cdat */ + (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes] = curr_cdatp; + /* Push the cdat onto the cdat_stack */ + *++cdat_stackp = curr_cdatp; + +} + +void +pop_cdat +() +{ + cdat_stackp--; +} + +/* Called in the reduction of a set. While both odats (eles and sets) + have identical label terminals, we are unable to give a single grammatical rule + for both due to how we allocate odats in the odat buf. Due to the + nature of bottom up parsing, the set label is recognized first, and then the + sets elements are recognized. This means that after we have processed the sets elemenets, + the curr_odat is going to be the last element and NOT the set that was first allocated. + To get around this, we create a global variable set_odatp that will store the pointer + to the odat when it is first allocated (in insert_set_label()) so that insert_set() can + have access to it. Curr set points the sets representation in the cdat, curr_set_odatp + points to the sets representation as an odat*/ + +void +insert_set_label +( char* name, + uint64_t ref_id +) +{ + + struct set* curr_setp; + + curr_setp = curr_set(); + curr_set_odatp = alloc_odat(); + + memmove(curr_set_odatp->name, name, 32); + memmove(curr_setp->name, name, 32); + + if(ref_id != -1) + { curr_set_odatp->ref_id = ref_id; + curr_setp->ref_id = ref_id; + } + else + { curr_setp->ref_id = ss_ref_id; + curr_set_odatp->ref_id = ss_ref_id++; + } + +} + +/* Inserting a olink instead of a set. Set is really just a placeholder + for another set. Allocate the memory for the set so taht it can be populated*/ +void +insert_set_olink +( uint64_t ref_id +) +{ + struct set* curr_setp; + + curr_setp = curr_set(); + + curr_setp->ref_id = ref_id; + +} + +void +insert_set_vlink +( uint64_t ref_id, + char* anim_name +) +{ + struct cdat* curr_cdatp; + struct odat* curr_odatp; + struct link* curr_linkp; + + + curr_cdatp = curr_cdat(); + curr_odatp = curr_odat(); + curr_linkp = alloc_link(); + + /* Insert vlink into link_stack so that it gets processed at + output time */ + curr_linkp->type = 2; + /* Store the target odat information*/ + curr_linkp->link_t.vlink.ref_id = ref_id; + memmove(curr_linkp->link_t.vlink.anim_name, anim_name, 32); + /* Store the linking odat/cdat information */ + curr_linkp->classp = curr_cdatp; + curr_linkp->odatp = curr_odatp; + curr_linkp->set_idx = curr_cdatp->num_sets; + curr_linkp->ele_idx = -1; + +} + +/* Svlinks dont have animation names */ +void +insert_set_svlink +( uint64_t ref_id +) +{ + struct cdat* curr_cdatp; + struct link* curr_linkp; + + curr_cdatp = curr_cdat(); + curr_linkp = alloc_link(); + + /* Insert svlink into link_stack so that it gets processed at + output time */ + curr_linkp->type = 3; + curr_linkp->classp = curr_cdatp; + curr_linkp->set_idx = curr_cdatp->num_sets; + curr_linkp->ele_idx = -1; + curr_linkp->link_t.svlink.ref_id = ref_id; + +} + +/* At the point of reducing to a set, most of the + sets odat information has already been populated + during the reduction of its right hand side + non terminals (hitbox, root, quad_list). */ +void +insert_set +() +{ uint64_t ref_id; + struct odat* curr_odatp; + struct cdat* curr_cdatp; + struct set* curr_setp; + struct ref* prev_refp; + struct ref* curr_refp; + struct vdat* curr_vdatp; + + curr_odatp = curr_set_odatp; //allocated at insert_set_label, preserved in global space + curr_cdatp = curr_cdat(); + curr_setp = curr_set(); + prev_refp = curr_ref(); + curr_refp = alloc_ref(); + curr_vdatp = curr_vdat(); + + curr_vdatp->creator = curr_set_odatp; + + curr_setp->cdat_idx = curr_cdatp->idx; //does a set need its class idx? + memmove(curr_setp->name, curr_odatp->name, 32); + curr_cdatp->num_sets++; + + curr_odatp->cdat_idx = curr_cdatp->idx; + curr_odatp->refp = curr_refp; + + ref_id = curr_setp->ref_id; // ref_id set by insert_set_label(name, ref_id) + + curr_refp->ref_id = ref_id; + curr_refp->lastref = prev_refp; + curr_refp->odatp = curr_odatp; + prev_refp->nextref = curr_refp; + + + +} +/* Created as a seperate function, instead of setting the ODATS vdat_id and + calling inc_vdat() inside of insert_set(), to account for the set reduction + where a vdat is not created (o/v/svlinks). */ +void +insert_set_vdatid +() +{ + struct vdat* curr_vdatp; + + curr_vdatp = curr_vdat(); + + curr_set_odatp->vdat_id = num_vdats; //no vdat_id for odats that have vlinks/svlinks + curr_set_odatp->vdatp = curr_vdatp; + curr_set_odatp = NULL; //This sets odat shouldnt be modified after populating odats vdat info +} + +/* Populates the odat name and ref_id for odat, allocate the odat here for the rest of + the functions to use via curr_odat(). */ +void +insert_ele_label +( char* name, + uint64_t ref_id +) +{ + struct odat* curr_odatp; + + curr_odatp = alloc_odat(); + + memmove(curr_odatp->name, name, 32); + + if(ref_id != -1) + curr_odatp->ref_id = ref_id; + else + curr_odatp->ref_id = ss_ref_id++; + +} + +/* We don't make an odat here, at output time we will resolve + the ref_id to the corresponding odat. */ +void +insert_ele_olink +( uint64_t ref_id +) +{ + /* Do nothing because we already know the ref_id that + the odat needs for this element (in the quad_file) */ +} + +void +insert_ele_vlink +( uint64_t ref_id, + char* anim_name +) +{ + struct cdat* curr_cdatp; + struct set* curr_setp; + struct link* curr_linkp; + + curr_cdatp = curr_cdat(); + curr_setp = curr_set(); + curr_linkp = alloc_link(); + + /* Insert vlink into link_stack so that it gets processed at + output time */ + curr_linkp->classp = curr_cdatp; + curr_linkp->type = 2; + curr_linkp->set_idx = curr_cdatp->num_sets; + //curr_linkp->ele_idx = curr_setp->num_ele; + curr_linkp->link_t.vlink.ref_id = ref_id; + memmove(curr_linkp->link_t.vlink.anim_name, anim_name, 32); + +} + +void +insert_ele_svlink +( uint64_t ref_id +) +{ + struct cdat* curr_cdatp; + struct set* curr_setp; + struct link* curr_linkp; + + curr_cdatp = curr_cdat(); + curr_setp = curr_set(); + curr_linkp = alloc_link(); + + curr_linkp->classp = curr_cdatp; + curr_linkp->type = 3; + + //curr_linkp->ele_idx = curr_setp->num_ele; + curr_linkp->link_t.svlink.ref_id = ref_id; + + +} + +//Insert element into odat_buf and cdatpages +void +insert_ele() +{ + uint64_t ref_id; + struct cdat* curr_cdatp; + struct odat* curr_odatp; + struct vdat* curr_vdatp; + struct set* curr_setp; + struct ele* curr_elep; + struct ref* curr_refp; + struct ref* prev_refp; + + + curr_odatp = curr_odat(); //malloced @ insert_ele_label + curr_vdatp = curr_vdat(); + curr_setp = curr_set(); + prev_refp = curr_ref(); + curr_refp = alloc_ref(); + + curr_vdatp->creator = curr_odatp; + + /* Populate odat for ele */ + curr_odatp->cdat_idx = curr_cdatp->idx; + curr_odatp->refp = curr_refp; + + ref_id = curr_odatp->ref_id; + + curr_refp->ref_id = ref_id; + curr_refp->lastref = prev_refp; + curr_refp->odatp = curr_odatp; + prev_refp->nextref = curr_refp; + +} + +void +insert_ele_vdatid +() +{ struct odat* curr_odatp; + curr_odatp = curr_odat(); + curr_odatp->vdat_id = num_vdats; +} + +void +insert_quad +( void* quad_filep +) +{ + struct odat* curr_odatp; + + curr_odatp->quad_filep = quad_filep; +} + +/* Inserting the hitbox into the set + odat. Elements that don't have + a hitbox will use the sets root. */ +void +insert_hitbox +( int hitbox +) +{ struct odat* curr_odatp; + + curr_odatp = curr_odat(); + curr_odatp->hitbox = hitbox; +} + +/* Inserting the root into the set + odat. Elements that don't have + a root will use the sets root. */ +void +insert_root +( int x, + int y, + int z +) +{ struct odat* curr_odatp; + + curr_odatp = curr_odat(); + curr_odatp->root.x = x; + curr_odatp->root.y = y; + curr_odatp->root.z = z; +} + + +void +insert_framesheet +( char direction, + char* name, + uint64_t ref_id, + int height , + int width, + int num_frames +) +{ struct vdat* curr_vdatp; + struct model* curr_modelp; + + curr_vdatp = curr_vdat(); + curr_modelp = curr_model(); + + curr_modelp->spritesheet[(int)direction].height = height; + curr_modelp->spritesheet[(int)direction].width = width; + curr_modelp->spritesheet[(int)direction].num_frames = num_frames; + curr_vdatp->num_models++; +} + +void +insert_frame_pointer +( char direction, + void* frame +) +{ struct model* curr_modelp; + + curr_modelp = curr_model(); + + curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame; +} + diff --git a/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/ir.h b/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/ir.h new file mode 100755 index 0000000..3b1d75c --- /dev/null +++ b/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/ir.h @@ -0,0 +1,271 @@ +/*!@file + \brief Intermediate Representation (IR) between Directory Structure and Engine Grammar + \details The IR serves as a storage structure that is populated during the + parsing of the input directory structure. After parsing is complete, + the IR will be condensed (removed of excess allocated space) and then + output as the Engine Grammar. In this file we describe the semantic actions + that are called at each step, and the memory buffers that they populate. + See parser.y for the description on how the input grammar is constructed, + and where/when semantic actions are called. + TODO: or just write it here. + \author Jordan Lavatai + \date Aug 2016 + ----------------------------------------------------------------------------*/ + + +#include + +#define BUF_SIZE 256 +#define MAX_SETS 256 +#define MAX_ELES 256 +#define MAX_QUADS 256 +#define MAX_MODELS 256 +#define MAX_POSTS 256 +#define MAX_CLASS_DEPTH 256 +#define MAX_CLASSES 256 +#define MAX_FRAMES 256 +#define PTRS_IN_PAGE 1024 +#define MAX_CHUNKS 256 +#define PAGES_PER_CHUNK 16 + +/* Sets: elements. The set is populated at parse time AFTER the + elements are populated, due to the nature of bottom up parsing. */ + +struct set { + char name[32]; + uint64_t ref_id; + int cdat_idx; +}; + +/* Cdats: A cdat is a class data structure. Cdats serve as the central */ +/* data types of the IR. For each cdat, sets and element */ +/* ref_ids must be dereferenced to determine the odat information. Cdats */ +/* contain pointers to their subclasses so that the relationship between */ +/* classes can be determined, but the subclasses are not represented inside */ +/* of the cdat itself but rather in subsequent cdats in cdat_buf. We */ +/* can determine the number of subclasses (the last index into cdat_buf */ +/* that represents a subclass of some arbitrary cdat) each cdat has by */ +/* incrementing num_classes during parse time. */ +/* TODO: Should classes point to their parent class? */ + +struct cdat { + char name[32]; + int idx; + int num_classes; + int num_sets; + struct cdat* class_list[MAX_CLASSES]; + struct set set_list[MAX_SETS]; +}; + +/* The cdat_stack is a stack pointers to cdat pointers, the top of which is + the cdat that is currently being parsed. Whenever a new cdat is recognized + by the grammar (CLOPEN), a cdat is pushed onto the cdat_stack, and we refer + to this cdat through the macro CURR_CDAT. By keeping a cdat_stack, we have + access to the current cdat so that the elements and sets can populate themselves + in the cdat accordingly. */ + + +/* Refs: Each set/ele has a reference to its object data (odat) through a ref_id. + Ref_ids are unsigned 64 byte integers that map to the hex values RGBA. During + the construction of the directory structure, users can choose a RGBA value for + each object that any other object can refer to via links (see link). If a user + does not choose an RGBA value, then the object is given one from the system space. + We maintain a doubly linked list of refs in the ref_buf at parse time so that + links can be resolved after the parsing of the directory structure is complete. + For every 16th ref, we create a post so that we can reduce on the search time for + a random access. */ + +struct ref { + int type; + struct ref* nextref; + struct ref* lastref; + struct odat* odatp; + uint64_t ref_id; //0xFFFFFF->digit +}; + + +/* Links: At parse time, a set/ele can include a link in their + grammar representation instead of the actual data and this signifies + to the APC that that set/ele wishes to use the data of another + set/ele, either its video data (vdat) or object data (odat). The link + itself contains the type of link it is, the ref_id OR name, and + which set/ele created the link. During parse time, links can be made + to o/vdats that have yet to be parsed. In order to accomodate for this, + we resolve all links AFTER parse time by iterating through the link_buf, + finding the ref_id that was stored for some object (if the ref_id exists), + and creating a relative pointer from the original object to the data that + was linked */ + +/* Svlinks stand for short vlink, which is a link to a vdat. svlinks + differ from vlinks because they do not have a name */ + +struct svlink { + uint64_t ref_id; +}; + +/* A vlink is what it sounds like, a link to a vdat */ +struct vlink { + uint64_t ref_id; + char anim_name[32]; +}; + +union link_t { + struct vlink vlink; + struct svlink svlink; +}; + +/* From: src odat ()To: dest odat (ref_id)*/ +struct link { + int type; //1 = olink, 2 = vlink, 3 = svlink + union link_t link_t; + struct cdat* classp; + struct odat* odatp; + int set_idx; + int ele_idx; +}; + + +/* Odats: Odats consist of the object data necessary for + each object. Odats are sometimes referred to as archetypes + at compile-time, in order to distinguish the difference from + a runtime object and a compile-time object. + TODO: Need more info about objects at runtime, to described + the reasoning behind odat structure at compile-time*/ + +struct root { + int x, y, z; +}; + +struct odat { + char name[32]; + struct vdat* vdatp; + int vdat_id; // + int cdat_idx; + int hitbox; + uint64_t ref_id; + struct root root; + struct ref* refp; /* pointer to it's ref on ref_list */ + void* quad_filep; +}; + +struct odat* curr_set_odatp; //when a set has elements, insert_set() can no longer + //refer to its odat via curr_odat, so save the set odat. + +/* A framesheet is a grouping of animation frames in + a single direction (N,W,S,E) */ +struct framesheet { + int width; + int height; + int num_frames; + void* frames[MAX_FRAMES]; +}; + +/* A model is a collection of framesheets for every + direction (N,W,S,E,NW,NE,SW,SE)*/ +/* NAMED spritesheet */ +struct model { + char name[32]; + struct framesheet spritesheet[8]; //one for each +}; + +/* Vdat: Vdats are the video data of each object. They can not be + created as a stand alone object (because they consist solely + of animation information and not the skeleton on which the + animation manipulates). Vdats have a list of models for every + animation that the vdats odat can do for that vdat*/ +struct vdat { + struct odat* creator; //pointer to odat that made this vdat + int num_models; + struct model model_list[MAX_MODELS]; +}; + +/* Called after the cdat open operator has been recognized in grammar. Allocates + the space for a cdat on the cdat_buf, pushes that pointer onto + the cdat_stack */ +void +push_cdat(char*); + +/* Called after a cdat end operator has been recognized in grammar. Sets + top stack cdat ** to null and decrements stack pointer */ +void +pop_cdat(void); + +/* Called after an odat has been populated. Allocates memory for + the next odat. */ + +void +insert_set_label(char*, uint64_t); + +/* Populate the sets representation in CURR_CDAT with a ref_id and insert a link + into the link_buf that will resolve the ref_id to an actual odat after parse time. */ +void +insert_set_olink(uint64_t); + +/* Put the vlink in the link_buf to be processed after parsetime */ +void +insert_set_vlink(uint64_t, char*); + +/* Put svlink in the link_buf to be processed after parsetime */ +void +insert_set_svlink(uint64_t); + +/* Called for every set reduction except for sets with olinks. Populates the + set data structures in the CDAT and in the ODAT. Uses the name and ref_id + from insert_set_label. Also inserts a ref into the ref_buf with the CURR_ODAT + pointer so that we can also resolve the odat from its ref_id. */ +void +insert_set(void); + +/* Insertion of eles is practically equivalent to how sets are inserted because both + share the same data type (ODAT). Like sets, eles have links, labels + and odats. Eles have the added notion of a parent set, and so must be inserted + into said parent set, but this is the only place they truly differ from sets. */ + +void +insert_set_vdatid(void); + +void +insert_ele_label(char*, uint64_t); + +/* Insert an ele olink into the CURR_ODAT */ +void +insert_ele_olink(uint64_t); + +/* Insert a ele vlink into CURR_ODAT*/ +void +insert_ele_vlink(uint64_t, char*); + +/* Inserts an ele short vlink into CURR_ODAT*/ +void +insert_ele_svlink(uint64_t); + +/* inserts ele into CURR_CLASS and CURR_ODAT */ +void +insert_ele(void); + +void +insert_ele_vdatid(void); + +/* Inserts the hitbox into the CURR_ODAT */ +void +insert_hitbox(int); + +/* Inserts the root into the CURR_ODAT */ +void +insert_root(int, int, int); + +/* Inserts a quad into the CURR_ODAT */ +void +insert_quad(void*); + +void +insert_model(void); + +void +insert_framesheet(char, char*, uint64_t, int, int, int); + +void +insert_frame_pointer(char, void*); + +void +alloc_vdat(void); diff --git a/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/irmem.c b/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/irmem.c new file mode 100644 index 0000000..3716d59 --- /dev/null +++ b/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/irmem.c @@ -0,0 +1,330 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct cdat* +alloc_cdat(void); +struct odat* +alloc_odat(void); +void +alloc_vdat(void); +struct link* +alloc_link(void); +struct ref* +alloc_ref(void); +struct cdat* +curr_cdat(void); +struct odat* +curr_odat(void); +struct vdat* +curr_vdat(void); +struct set* +curr_set(void); +struct ref* +curr_ref(void); +struct model* +curr_model(void); +void +inc_posts(void); + +#define PAGES_PER_CHUNK 16 + +//"type free" chunk stacking +struct chunk_stack +{ void* chunks[MAX_CHUNKS]; + void* *csp; //chunk stack pointer + void* dsp[MAX_CHUNKS]; //dat stack pointer (per chunk) + int chunk_size; //size of a chunk (including its forfeited page) + int max_dats; //number of dats per chunk for this stack +} ocs, vcs, ccs, rcs, lcs, pcs; //odat, vdat, and cdat, ref, link, post stacks + +//type safety handled by macro expansion (do not call these directly from code, make dependent macros for access to these) +#define CHUNKS_LEN(STACK) ((STACK).csp - (STACK).chunks) +#define CURRENT_CHUNK(STACK) ((STACK).chunks[CHUNKS_LEN(STACK) - 1]) +#define CHUNKS_FULL(STACK) ( (STACK).csp >= \ + (STACK).chunks + MAX_CHUNKS * (STACK).chunk_size) +#define CURRENT_DSP(STACK,TYPE) ((TYPE*) ((STACK).dsp[CHUNKS_LEN(STACK) - 1])) +#define DATA_FULL(STACK,TYPE) ((void*) CURRENT_DSP(STACK,TYPE) >= \ + (CURRENT_CHUNK(STACK) + (STACK).chunk_size)) +#define CSP_PUSH(STACK) (*(++(STACK).csp) = malloc((STACK).chunk_size)) +#define CURRENT_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 1]) +#define PREVIOUS_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 2]) +#define ALLOC_DAT(STACK,TYPE) (++CURRENT_DATP(STACK,TYPE)) +#define INIT_STACK(STACK,TYPE) \ + { int i; \ + (STACK).chunk_size = PAGES_PER_CHUNK * pagesize; \ + (STACK).max_dats = (STACK).chunk_size / sizeof (TYPE); \ + CSP_PUSH(STACK); \ + for( i = 0; i < MAX_CHUNKS; i++){ \ + (STACK).dsp[i] += pagesize; \ + } \ + } +//Stack-specific macros (called directly from code (safety enforcement) +#define INIT_ODAT() (INIT_STACK(ocs, struct odat)) +#define CURRENT_ODAT() (CURRENT_DATP(ocs,struct odat)) +#define ODAT_FULL() (DATA_FULL(ocs,struct odat)) +#define ODAT_ALLOC() (ALLOC_DAT(ocs,struct odat)) +#define OCS_FULL() (CHUNKS_FULL(ocs)) +#define INIT_VDAT() (INIT_STACK(vcs, struct vdat)) +#define CURRENT_VDAT() (CURRENT_DATP(vcs,struct vdat)) +#define VDAT_FULL() (DATA_FULL(vcs,struct vdat)) +#define VDAT_ALLOC() (ALLOC_DAT(vcs,struct vdat)) +#define VCS_FULL() (CHUNKS_FULL(vcs)) +#define INIT_CDAT() (INIT_STACK(ccs, struct cdat)) +#define CURRENT_CDAT() (CURRENT_DATP(ccs,struct cdat)) +#define CDAT_FULL() (DATA_FULL(ccs, struct cdat)) +#define CDAT_ALLOC() (ALLOC_DAT(ccs, struct cdat)) +#define CCS_FULL() (CHUNKS_FULL(ccs)) +#define INIT_LINK() (INIT_STACK(lcs, struct link)) +#define CURRENT_LINK() (CURRENT_DATP(lcs,struct link)) +#define LDAT_FULL() (DATA_FULL(lcs, struct link)) +#define LDAT_ALLOC() (ALLOC_DAT(lcs, struct link)) +#define LCS_FULL() (CHUNKS_FULL(lcs)) +#define INIT_POST() (INIT_STACK(rcs, struct ref)) +#define CURRENT_POST() (CURRENT_DATP(pcs,struct ref)) +#define POST_FULL() (DATA_FULL(pcs,struct ref)) +#define POST_ALLOC() (ALLOC_DAT(pcs,struct ref)) +#define PCS_FULL() (CHUNKS_FULL(pcs)) +#define INIT_REF() (INIT_STACK(rcs, struct ref)) +#define CURRENT_REF() (CURRENT_DATP(rcs,struct ref)) +#define PREVIOUS_REF() (PREVIOUS_DATP(rcs, struct ref)) +#define REF_FULL() (DATA_FULL(rcs,struct ref)) +#define REF_ALLOC() (ALLOC_DAT(rcs,struct ref)) +#define RCS_FULL() (CHUNKS_FULL(rcs)) +//Metadata +#define CURRENT_SET() (CURRENT_CDAT()->set_list[CURRENT_CDAT()->num_sets]) +#define CURRENT_MODEL() (CURRENT_VDAT()->model_list[CURRENT_VDAT()->num_models]) + + +#define CURR_QUAD (CURR_ODAT->quad_file) + +long pagesize; + +int num_cdats = 0; + +struct cdat* cdat_stack[MAX_CLASSES]; +struct cdat** cdat_stackp; + +int num_odats = 0; + +int num_vdats = 0; + +int num_refs = 0; +uint64_t ss_ref_id = 0x00FFFFFF; /* system space for ref_ids */ + +int num_posts = 0; + +int num_links = 0; + + +/* The initalization function of the IR. */ +int +ir_init() +{ + + char root[4] = "root"; + + pagesize = sysconf(_SC_PAGESIZE); + + INIT_CDAT(); + *cdat_stackp = CURRENT_CDAT(); + memmove((*cdat_stackp)->name, root, 32); + + INIT_ODAT(); + INIT_VDAT(); + INIT_LINK(); + INIT_REF(); + INIT_POST(); + + + return 0; + +} + +void +ir_quit() +{ + int i; + + for(i = 0; i < CHUNKS_LEN(ccs) ; i++) + { + free(ccs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(ocs); i++) + { + free(ocs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(vcs) ; i++) + { + free(vcs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(rcs); i++) + { + free(rcs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(lcs); i++) + { + free(lcs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(pcs); i++) + { + free(pcs.chunks[i]); + } + +} + +struct cdat* +alloc_cdat() +{ + num_cdats++; + if(CDAT_FULL()) + { if(CCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) cdats ", num_cdats); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(ccs); + } + else + CDAT_ALLOC(); + + return CURRENT_CDAT(); +} + +//these should probably be inline +struct odat* +alloc_odat +() +{ + num_odats++; + if(ODAT_FULL()) + { if(!OCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) odats ", num_odats); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(ocs); + } + else + ODAT_ALLOC(); + + return CURRENT_ODAT(); +} + +void +alloc_vdat +() +{ num_vdats++; + if(VDAT_FULL()) + { if(!VCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) vdats ", num_vdats); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(vcs); + } + else + VDAT_ALLOC(); +} + +struct link* +alloc_link +() +{ num_links++; + if(LDAT_FULL()) + { if(!LCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) links ", num_links); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(lcs); + } + else + LDAT_ALLOC(); + + return CURRENT_LINK(); + +} + +struct ref* +alloc_ref +() +{ num_refs++; + if(REF_FULL()) + { if(!RCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) refs ", num_refs); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(rcs); + } + else + REF_ALLOC(); + + + if(num_refs % 16 == 0) + { CURRENT_POST() = CURRENT_REF(); + inc_posts(); + } + + return CURRENT_REF(); +} + +void +inc_posts() +{ num_posts++; + if(POST_FULL()) + { if(!PCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) refs ", num_posts); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(pcs); + } + else + POST_ALLOC(); + +} + +struct cdat* +curr_cdat +() +{ + return (*cdat_stackp); +} + +struct odat* +curr_odat +() +{ + return CURRENT_ODAT(); +} +struct vdat* +curr_vdat +() +{ + return CURRENT_VDAT(); +} +struct set* +curr_set +() +{ + return &CURRENT_SET(); +} +struct ref* +curr_ref +() +{ + return CURRENT_REF(); +} +struct model* +curr_model +() +{ + return &CURRENT_MODEL(); +} diff --git a/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/parser.y b/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/parser.y new file mode 100644 index 0000000..e6d145c --- /dev/null +++ b/org/data/fb/24c302-4743-4a45-845a-4249d2b1a378/parser.y @@ -0,0 +1,206 @@ +/* Asset Package Compiler */ +%code requires{ + #include +} +%{ + #include + #include + #include + #include + #include + + extern int lexer_init(); + extern int lexer(); + #define yylex lexer + + + void yyerror(); +%} +%define parse.error verbose +%define lr.type ielr + +%union { + uint64_t ref; + int val; + char *str; + void *voidp; + +} + + //operators +%token CLOPEN // ( +%token CLCLOSE // ) +%token SOPEN // { +%token SCLOSE // } +%token EOPEN // [ +%token ECLOSE // ] +%token VOPEN // / +%token VCLOSE // \ + +%token QOPEN // ! +%token QCLOSE // @ +%token RT // & +%token HB // # +//nonterminal types +%type olink +%type ele_svlink +%type set_svlink +//terminals +%token NUM +%token STR +%token SS +%token NAME +%token REF +%token SSD +%token FPTR +%token QPTR +// Change width, height, num_ptrs to NUM because +// when scanning, we can't determine which NUM +// is which. +%token WIDTH +%token HEIGHT +%token NUM_PTRS +//precedence +%precedence LP +%precedence MP +%precedence HP + + /* Syntax Directed Translation Scheme of the APC grammar */ + +/* Rules */ +%% +cdat_buf: +class_list +; + +class_list: +class_list class +| class +; + +class: + CLOPEN NAME {push_cdat($2);} class_block CLCLOSE {pop_cdat();}; +; + +class_block: +class_list +| class_list set_list +| set_list +; + +set_list: +set_list set +| set +; + +root: +RT NUM NUM NUM {insert_root($2, $3, $4);}; +; + +quad_file: +QOPEN QPTR QCLOSE {insert_quad($2);}; + +hitbox: +HB NUM {insert_hitbox($2);} +; + +set_map_data: +quad_file +| quad_file hitbox +| quad_file hitbox root +| hitbox root +| hitbox +| root +; + +set: +SOPEN set_label set_map_data element_list {alloc_vdat();} vdat SCLOSE {insert_set(); insert_set_vdatid();}; +| SOPEN set_label set_map_data element_list set_vlink SCLOSE {insert_set();}; +| SOPEN set_label set_map_data element_list set_svlink SCLOSE {insert_set_svlink($5); insert_set(); }; +| SOPEN set_label element_list {alloc_vdat();} vdat SCLOSE {insert_set(); insert_set_vdatid();}; +| SOPEN set_label element_list set_vlink SCLOSE {insert_set(); } +| SOPEN set_label element_list set_svlink SCLOSE {insert_set_svlink($4); insert_set();}; +| SOPEN olink SCLOSE {insert_set_olink($2);}; +; + + +set_label: +HP NAME REF {insert_set_label($2,$3);}; +| LP NAME {insert_set_label($2, -1);}; +; + +set_svlink: +REF + +; + +set_vlink: +REF NAME {insert_set_vlink($1, $2);}; +; + +olink: +REF +; + +//parent_id is the set_index of the subclass_index. +element_list: +element_list element MP +| element LP +; + +ele_label: +HP NAME REF {insert_ele_label($2, $3);}; +| LP NAME {insert_ele_label($2, -1);}; +; + +ele_vlink: +REF NAME {insert_ele_vlink($1, $2);}; +; + +ele_svlink: +REF +; + +element: +EOPEN ele_label hitbox root {alloc_vdat();} vdat ECLOSE {insert_ele(); insert_ele_vdatid();}; +| EOPEN ele_label hitbox root ele_vlink ECLOSE {insert_ele(); }; +| EOPEN ele_label hitbox root ele_svlink ECLOSE {insert_ele_svlink($5);insert_ele(); }; +| EOPEN ele_label root {alloc_vdat();} vdat ECLOSE {insert_ele(); insert_ele_vdatid();}; +| EOPEN ele_label root ele_vlink ECLOSE {insert_ele(); }; +| EOPEN ele_label root ele_svlink ECLOSE {insert_ele_svlink($4); insert_ele(); }; +| EOPEN olink ECLOSE {insert_ele_olink($2);}; +; + +vdat: +VOPEN model_list VCLOSE +; + +model_list: +model_list model +| model + ; + +model: +spritesheet LP +; + +spritesheet: +spritesheet HP framesheet +| framesheet +; + +framesheet: +SSD NAME REF HEIGHT WIDTH NUM_PTRS frame_pointers LP {insert_framesheet($1, $2, $3, $4, $5, $6);}; +; + +frame_pointers: +frame_pointers SSD HP FPTR {insert_frame_pointer($2, $4);}; +| SSD FPTR {insert_frame_pointer($1, $2);}; +; + +%% + +void +yyerror (char const *s) +{ fprintf(stderr, "%s\n", s); +} diff --git a/org/schedule.org b/org/schedule.org new file mode 100644 index 0000000..b398d1a --- /dev/null +++ b/org/schedule.org @@ -0,0 +1,95 @@ +* Project Deadlines + +** October +*** TODO APC + :PROPERTIES: + :ATTACH_DIR: ~/proj/the_march/src/apc + :END: +**** TODO Scanner :ATTACH: + :PROPERTIES: + :Attachments: scanner.c + :ID: 2dec5876-7b81-4b9c-97fe-03b152fa276a + :END: +**** TODO Lexer :ATTACH: + :PROPERTIES: + :Attachments: lexer.c lexer_lex.rl + :ID: faf3ff67-f8e9-41fe-9a32-2ced4bbf5b99 + :END: +**** TODO Parser/IR :ATTACH: + :PROPERTIES: + :Attachments: parser.y irmem.c ir.c ir.h + :ID: fb24c302-4743-4a45-845a-4249d2b1a378 + :END: +**** TODO Output + DEADLINE: <2016-10-20 Thu> +*** TODO Test Suite for APC + DEADLINE: <2016-10-20 Thu> +*** TODO Animation Viewer + DEADLINE: <2016-10-31 Mon> + +** November +*** TODO Core State Machine + DEADLINE: <2016-11-10 Thu> +*** TODO Renderer + DEADLINE: <2016-11-10 Thu> +*** TODO World Generator - Beta + DEADLINE: <2016-11-20 Sun> +*** TODO Core Improvements + DEADLINE: <2016-11-20 Sun> +*** TODO Front-end Hooks + DEADLINE: <2016-11-20 Sun> +*** TODO World Generator - Stable + DEADLINE: <2016-11-30 Wed> +*** TODO Physics Engine + SCHEDULED: <2016-11-30 Wed> + DEADLINE: <2016-12-20 Tue> +*** TODO Actors + DEADLINE: <2016-11-30 Wed> +*** TODO Audio Backend + DEADLINE: <2016-11-30 Wed> + +** December +*** TODO Account Management + DEADLINE: <2016-12-10 Sat> +*** TODO User Management + DEADLINE: <2016-12-10 Sat> +*** TODO Controllers - Beta + DEADLINE: <2016-12-10 Sat> +*** TODO Internal Data Handling + DEADLINE: <2016-12-10 Sat> +*** TODO Network Skeleton + DEADLINE: <2016-12-10 Sat> +*** TODO Social Media + SCHEDULED: <2016-12-10 Sat> +*** TODO Core Gameplay + SCHEDULED: <2016-12-20 Tue> +*** TODO Account Management - Stable + DEADLINE: <2016-12-20 Tue> +*** TODO Controllers - Stable + DEADLINE: <2016-12-20 Tue> + +** Christmas Holiday (December 21 - January 5) +*** TODO Gameplay Developments +*** TODO Front-End Improvements (remote) +*** TODO AI Start +*** TODO Website Beta + +** January +*** TODO Gameplay - Win Conditions + DEADLINE: <2017-01-10 Tue> +*** TODO Social Media Integration + DEADLINE: <2017-01-10 Tue> +*** TODO Viable AI (Lua ^ JS) + DEADLINE: <2017-01-20 Fri> + +** February +*** TODO Beta Deployment + DEADLINE: <2017-02-01 Wed> +*** TODO Multiplay Beta + DEADLINE: <2017-02-01 Wed> +*** TODO Early Access for Marketing + DEADLINE: <2017-02-01 Wed> + + + +