/** * CTRParserReference * * Generates the nodes to respresent a variable or property. */ ctr_tnode* ctr_cparse_ref() { ctr_tnode* r; char* tmp; ctr_clex_tok(); r = CTR_PARSER_CREATE_NODE(); r->type = CTR_AST_NODE_REFERENCE; r->vlen = ctr_clex_tok_value_length(); tmp = ctr_clex_tok_value(); if (strncmp("my", tmp, 2)==0 && r->vlen == 2) { int t = ctr_clex_tok(); if (t != CTR_TOKEN_REF) { printf("'My' should always be followed by property name!\n"); exit(1); } tmp = ctr_clex_tok_value(); r->modifier = 1; r->vlen = ctr_clex_tok_value_length(); } if (strncmp("var", tmp, 3)==0 && r->vlen == 3) { int t = ctr_clex_tok(); if (t != CTR_TOKEN_REF) { printf("'var' should always be followed by property name!\n"); exit(1); } tmp = ctr_clex_tok_value(); r->modifier = 2; r->vlen = ctr_clex_tok_value_length(); } r->value = ctr_malloc(r->vlen, 0); memcpy(r->value, tmp, r->vlen); return r; }
ctr_tnode* ctr_cparse_number() { char* n; ctr_tnode* r; long l; ctr_clex_tok(); r = CTR_PARSER_CREATE_NODE(); r->type = CTR_AST_NODE_LTRNUM; n = ctr_clex_tok_value(); l = ctr_clex_tok_value_length(); r->value = ctr_malloc(sizeof(char) * l, 0); memcpy(r->value, n, l); r->vlen = l; return r; }
/** * CTRParserString * * Generates a node to represent a string. */ ctr_tnode* ctr_cparse_string() { ctr_tnode* r; char* n; ctr_size vlen; if (ctr_mode_debug) printf("Parsing STRING. \n"); ctr_clex_tok(); r = CTR_PARSER_CREATE_NODE(); r->type = CTR_AST_NODE_LTRSTRING; n = ctr_clex_readstr(); vlen = ctr_clex_tok_value_length(); r->value = ctr_malloc(sizeof(char) * vlen, 0); memcpy(r->value, n, vlen); r->vlen = vlen; ctr_clex_tok(); /* eat trailing quote. */ return r; }
/** * Memory Management Adjust Memory Block Size (re-allocation) * Re-allocates Memory Block. * * Given the old pointer, the desired size, the original size and * the purpose for allocation, this function will attempt to * re-allocate the memory block. */ void* ctr_realloc(void* oldptr, uintptr_t size, uintptr_t old_size, int what) { char* nptr; nptr = ctr_malloc(size, what); memcpy(nptr, oldptr, old_size); return (void*) nptr; }
/** * CTRParserBlock * * Generates a set of AST nodes to represent a block of code. */ ctr_tnode* ctr_cparse_block() { ctr_tnode* r; ctr_tlistitem* codeBlockPart1; ctr_tlistitem* codeBlockPart2; ctr_tnode* paramList; ctr_tnode* codeList; ctr_tlistitem* previousListItem; ctr_tlistitem* previousCodeListItem; int t; int first; if (ctr_mode_debug) printf("Parsing code block.\n"); ctr_clex_tok(); r = CTR_PARSER_CREATE_NODE(); r->type = CTR_AST_NODE_CODEBLOCK; codeBlockPart1 = CTR_PARSER_CREATE_LISTITEM(); r->nodes = codeBlockPart1; codeBlockPart2 = CTR_PARSER_CREATE_LISTITEM(); r->nodes->next = codeBlockPart2; paramList = CTR_PARSER_CREATE_NODE(); codeList = CTR_PARSER_CREATE_NODE(); codeBlockPart1->node = paramList; codeBlockPart2->node = codeList; paramList->type = CTR_AST_NODE_PARAMLIST; codeList->type = CTR_AST_NODE_INSTRLIST; t = ctr_clex_tok(); first = 1; while(t == CTR_TOKEN_REF) { ctr_tlistitem* paramListItem = CTR_PARSER_CREATE_LISTITEM(); ctr_tnode* paramItem = CTR_PARSER_CREATE_NODE(); long l = ctr_clex_tok_value_length(); paramItem->value = ctr_malloc(sizeof(char) * l, 0); memcpy(paramItem->value, ctr_clex_tok_value(), l); paramItem->vlen = l; paramListItem->node = paramItem; if (first) { paramList->nodes = paramListItem; previousListItem = paramListItem; first = 0; } else { previousListItem->next = paramListItem; previousListItem = paramListItem; } t = ctr_clex_tok(); } if (t != CTR_TOKEN_BLOCKPIPE) { printf("Error expected blockpipe."); exit(1); } t = ctr_clex_tok(); first = 1; while((first || t == CTR_TOKEN_DOT)) { ctr_tlistitem* codeListItem; ctr_tnode* codeNode; if (first) { if (ctr_mode_debug) printf("First, so put back\n"); ctr_clex_putback(); } t = ctr_clex_tok(); if (t == CTR_TOKEN_BLOCKCLOSE) break; ctr_clex_putback(); codeListItem = CTR_PARSER_CREATE_LISTITEM(); codeNode = CTR_PARSER_CREATE_NODE(); if (ctr_mode_debug) printf("--------> %d %s \n", t, ctr_clex_tok_value()); if (t == CTR_TOKEN_RET) { codeNode = ctr_cparse_ret(); } else { codeNode = ctr_cparse_expr(0); } codeListItem->node = codeNode; if (first) { codeList->nodes = codeListItem; previousCodeListItem = codeListItem; first = 0; } else { previousCodeListItem->next = codeListItem; previousCodeListItem = codeListItem; } t = ctr_clex_tok(); if (t != CTR_TOKEN_DOT) { printf("Expected . but got: %d.\n", t); exit(1); } } return r; }
/** * CTRParserMessage * * Creates the AST nodes for sending a message. * * - precedence mode 0: no argument (allows processing of unary message, binary message and keyword message) * - precedence mode 1: as argument of keyword message (allows processing of unary message and binary message) * - precedence mode 2: as argument of binary message (only allows processing of unary message) */ ctr_tnode* ctr_cparse_message(int mode) { long msgpartlen; /* length of part of message string */ ctr_tnode* m; int t; char* s; char* msg; ctr_tlistitem* li; ctr_tlistitem* curlistitem; int lookAhead; int isBin; int first; ctr_size ulen; t = ctr_clex_tok(); msgpartlen = ctr_clex_tok_value_length(); if ((msgpartlen) > 255) { printf("Message too long\n"); exit(1); } m = CTR_PARSER_CREATE_NODE(); m->type = -1; s = ctr_clex_tok_value(); msg = ctr_malloc(255*sizeof(char), 0); memcpy(msg, s, msgpartlen); ulen = ctr_getutf8len(msg, msgpartlen); isBin = (ulen == 1); if (mode == 2 && isBin) { ctr_clex_putback(); return m; } if (isBin) { if (ctr_mode_debug) printf("Parsing binary message: '%s' (mode: %d)\n", msg, mode); m->type = CTR_AST_NODE_BINMESSAGE; m->value = msg; m->vlen = msgpartlen; li = CTR_PARSER_CREATE_LISTITEM(); if (ctr_mode_debug) printf("Binary argument start..\n"); li->node = ctr_cparse_expr(2); if (ctr_mode_debug) printf("Binary argument end..\n"); m->nodes = li; return m; } lookAhead = ctr_clex_tok(); ctr_clex_putback(); if (lookAhead == CTR_TOKEN_COLON) { if (mode > 0) { ctr_clex_putback(); if (ctr_mode_debug) printf("> End of argument, next token: %s .\n", msg); return m; } *(msg + msgpartlen) = ':'; msgpartlen += 1; if ((msgpartlen) > 255) { printf("Message too long\n"); exit(1); } if (ctr_mode_debug) printf("Message so far: %s\n", msg); m->type = CTR_AST_NODE_KWMESSAGE; t = ctr_clex_tok(); first = 1; while(1) { li = CTR_PARSER_CREATE_LISTITEM(); if (ctr_mode_debug) printf("Next arg, message so far: %s \n", msg); li->node = ctr_cparse_expr(1); if (ctr_mode_debug) printf("Argument of keyword message has been parsed.\n"); if (first) { m->nodes = li; curlistitem = m->nodes; first = 0; } else { curlistitem->next = li; curlistitem = li; } t = ctr_clex_tok(); if (ctr_mode_debug) printf("Next token after argument = %d \n", t); if (t == CTR_TOKEN_DOT) break; if (t == CTR_TOKEN_FIN) break; if (t == CTR_TOKEN_CHAIN) break; if (t == CTR_TOKEN_PARCLOSE) break; if (t == CTR_TOKEN_REF) { long l = ctr_clex_tok_value_length(); if ((msgpartlen + l) > 255) { printf("Message too long\n"); exit(1); } memcpy( (msg+msgpartlen), ctr_clex_tok_value(), l); msgpartlen = msgpartlen + l; *(msg + msgpartlen) = ':'; msgpartlen ++; t = ctr_clex_tok(); if (t != CTR_TOKEN_COLON) { printf("Expected colon. %s \n",msg); exit(1); } } } if (ctr_mode_debug) printf("Putting back.\n"); ctr_clex_putback(); /* not a colon so put back */ if (ctr_mode_debug) printf("Parsing keyword message: '%s' (mode: %d) \n", msg, mode); m->value = msg; m->vlen = msgpartlen; } else { m->type = CTR_AST_NODE_UNAMESSAGE; m->value = msg; m->vlen = msgpartlen; if (ctr_mode_debug) printf("Parsing unary message: '%s' (mode: %d) token = %d \n", msg, mode, lookAhead); } return m; }