static statement *parse_func_call(linked_list *tokens) { linked_list *accumulator = ll_new(); linked_iter iterator = ll_iter_head(tokens); statement *call = new(call); call->type = FUNC_CALL; call->data = ((parse_token*)ll_iter_next(&iterator))->data; call->children = ll_new(); int paren_level = 0; ll_iter_next(&iterator); //Discard opening parenthesis for(parse_token *current = ll_iter_next(&iterator); ll_iter_has_next(&iterator); current = ll_iter_next(&iterator)) { if(paren_level == 0 && (equals_string(current->data, ",") || equals_string(current->data, ")"))) { statement *parameter = parse_simple_expression(accumulator); if(parameter != NULL) ll_add_last(call->children, parameter); ll_clear(accumulator); } else { ll_add_last(accumulator, current); } if(equals_string(current->data, "(")) paren_level += 1; else if(equals_string(current->data, ")")) paren_level -= 1; } statement *parameter = parse_simple_expression(accumulator); if(parameter != NULL) ll_add_last(call->children, parameter); ll_destroy(accumulator); return call; }
file_contents parse(parse_source source) { file_contents contents; contents.imports = ll_new(); contents.enums = ll_new(); contents.unions = ll_new(); contents.structs = ll_new(); contents.functions = ll_new(); optional op = get_token(&source); while(op_has(op)) { parse_token current = *((parse_token*)op_get(op)); if(equals(current.data, new_slice("struct"))) { struct_declaration *dec = analyze_struct(&source); ll_add_last(contents.structs, dec); } else if(equals(current.data, new_slice("union"))) { struct_declaration *dec = analyze_struct(&source); ll_add_last(contents.unions, dec); } else if(equals(current.data, new_slice("func"))) { func_declaration *func = analyze_func(&source); ll_add_last(contents.functions, func); } else if(equals(current.data, new_slice("import"))) { import_declaration *imp = parse_import(&source); ll_add_last(contents.imports, imp); } else if(equals(current.data, new_slice("enum"))) { enum_declaration *enm = parse_enum(&source); ll_add_last(contents.enums, enm); }//TODO: Throw an error for an unexpected token op = get_token(&source); } return contents; }
static func_declaration *analyze_func(parse_source *source) { parse_token current = get_mandatory_token(source); func_declaration *func = new(func); func->parameters = ll_new(); if(current.type != WORD) { semantic_error("Function declaration must be in the form func <name>(<parameters>) <returntype> {<block>}", current.origin); } func->name = current.data; current = get_mandatory_token(source); if(current.data.data[0] != '(') { semantic_error("Function name must be followed by an open parenthesis", current.origin); } current = get_mandatory_token(source); while(current.data.data[0] != ')') { statement *name = new(name); name->type = NAME; name->children = ll_new(); if(current.type != WORD) { printf("%s\n", evaluate(current.data)); semantic_error("Parameter names must be a valid identifier", current.origin); } name->data = current.data; statement *param_type = parse_type_literal(source); ll_add_first(name->children, param_type); param_type->children = NULL; ll_add_last(func->parameters, name); current = get_mandatory_token(source); if(current.data.data[0] == ',') { current = get_mandatory_token(source); } } statement *returnType = parse_type_literal(source); func->type = returnType->data; free(returnType); current = peek_mandatory_token(source); if(current.data.data[0] != '{') { semantic_error("Function bodies must start with an open brace ('{')", current.origin); } int indent = 1; get_mandatory_token(source); func->root = new(func->root); func->root->type = ROOT; func->root->data = new_slice(""); func->root->children = ll_new(); while(indent > 0) { statement *state = get_expression(source, &indent); if(state != NULL) ll_add_last(func->root->children, state); } return func; }
static struct_declaration *analyze_struct(parse_source *source) { parse_token current = get_mandatory_token(source); struct_declaration *dec = new(dec); dec->name = current.data; dec->members = ll_new(); current = get_mandatory_token(source); if(current.data.data[0] != '{') { semantic_error("Expected opening brace after name in struct declaration.", current.origin); } current = get_mandatory_token(source); while(current.data.data[0] != '}') { struct_member *member = new(member); if(current.type != WORD) { semantic_error("Struct members must be declared as <name> <type>;", current.origin); } member->name = current.data; current = get_mandatory_token(source); if(current.type != WORD) { semantic_error("Struct members must be declared as <name> <type>;",current.origin); } member->type = current.data; current = get_mandatory_token(source); if(current.data.data[0] != ';') { semantic_error("Struct members must be declared as <name> <type>;", current.origin); } ll_add_last(dec->members, member); current = get_mandatory_token(source); } return dec; }
abLayer::abLayer(char* bg_filename) { sprites = ll_new(); lcd_image_t bg = {bg_filename, ST7735_WIDTH, ST7735_HEIGHT}; background = bg; hasDrawnOnce = false; toEraseCount = 0; }
void test_ll_sorted_index_of_1(CuTest* tc) { int i; ll* lst = ll_new(32); // Fill the list with L[i] = i^2 for (i=0; i<=10000; i++) ll_append(lst, i*i); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, -1)); CuAssertIntEquals(tc, 0, ll_sorted_index_of(lst, 0)); CuAssertIntEquals(tc, 1, ll_sorted_index_of(lst, 1)); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 2)); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 3)); CuAssertIntEquals(tc, 2, ll_sorted_index_of(lst, 4)); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 5)); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 960)); CuAssertIntEquals(tc, 31, ll_sorted_index_of(lst, 961)); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 962)); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 1023)); CuAssertIntEquals(tc, 32, ll_sorted_index_of(lst, 1024)); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 1025)); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 9999)); CuAssertIntEquals(tc, 100, ll_sorted_index_of(lst, 10000)); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 10001)); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 10000 * 10000 - 1)); CuAssertIntEquals(tc, 10000, ll_sorted_index_of(lst, 10000 * 10000 )); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 10000 * 10000 + 1)); // test again (jump accessors) CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 10000 * 10000 - 1)); CuAssertIntEquals(tc, 10000, ll_sorted_index_of(lst, 10000 * 10000 )); CuAssertIntEquals(tc, -1, ll_sorted_index_of(lst, 10000 * 10000 + 1)); }
t_ll* ll_new_n(void* data, int n) { t_ll *node; for (node = NULL; n > 0; n--) node = ll_append(node, ll_new(data)); return (node); }
llist * ll_insert(llist * list, const void * val, size_t size){ llist * n = NULL; n = ll_new(val, size); if (n == NULL) return NULL; return list != NULL ? ll_appendl(list, n): n; }
t_ll* ll_copy(t_ll* node) { t_ll* copied; if (node == NULL) return (NULL); copied = ll_new(node->data); copied->next = ll_copy(node->next); return (copied); }
int main(void) { LinkedList* list = ll_new(0); for(size_t i =1;i<=5;i++) ll_insert(list,i,i-1); ll_print(list); list = ll_reverse(list); ll_print(list); ll_free(list); return EXIT_SUCCESS; }
static enum_declaration *parse_enum(parse_source *source) { enum_declaration *dec = new(dec); parse_token current = get_mandatory_token(source); dec->name = current.data; dec->options = ll_new(); while(!equals_string(get_mandatory_token(source).data, "}")) { statement *expr = new(expr); current = get_mandatory_token(source); expr->data = current.data; ll_add_last(dec->options, expr); } return dec; }
void run_linked_list_tests() { char* inputs[] = { "item1", "item2", "item3", }; int num_inputs = sizeof(inputs) / sizeof(char*); char* data; // after init LinkedList *ll = ll_new(); assert("Starts empty", ll_is_empty(ll)); assert("Initial size is 0", ll_size(ll)==0); assert("Peek returns null", ll_peek(ll)==NULL); // after pushing one item ll_push(ll, inputs[0]); assert("Is not empty after pushing an item", !ll_is_empty(ll)); assert("Has size of 1 after pushing an item", ll_size(ll)==1); assert("Peeking returns the item we pushed", ll_peek(ll)==inputs[0]); // after two items ll_push(ll, inputs[1]); assert("Is not empty after pushing a second item", !ll_is_empty(ll)); assert("Has size of 2 after pushing a second item", ll_size(ll)==2); assert("Peeking returns the second item", ll_peek(ll)==inputs[1]); // after three items ll_push(ll, inputs[2]); assert("Is not empty after pushing a third item", !ll_is_empty(ll)); assert("Has size of 3 after pushing a third item", ll_size(ll)==3); assert("Peeking returns the third item", ll_peek(ll)==inputs[2]); // iterating through the items int index = num_inputs; int all_match = 1; ll_each(ll, char* input, ({ all_match &= (inputs[--index] == input); })); assert("It iterates the correct number of times", index==0); assert("The item provided matched each time", all_match); // popping an item data = ll_pop(ll); assert("It is not empty after popping the third item", !ll_is_empty(ll)); assert("Has size of 2 after popping the third item", ll_size(ll)==2); assert("Peeking returns the second item", ll_peek(ll)==inputs[1]); // cleanup ll_free(ll); }
static statement *parse_array_index(linked_list *tokens) { statement *index = new(index); index->type = OP_INDEX; index->data = new_slice(""); index->children = ll_new(); statement *name = new(name); name->type = NAME; name->data = ((parse_token*)ll_get_first(tokens))->data; name->children = NULL; ll_add_first(index->children, name); linked_list *inside_list = ll_duplicate(tokens); ll_remove_first(inside_list); //Remove name ll_remove_first(inside_list); //Remove [ ll_remove_last(inside_list); //Remove ] statement *inside = parse_simple_expression(inside_list); ll_destroy(inside_list); ll_add_last(index->children, inside); return index; }
void test_ll_sorted_contains_1(CuTest* tc) { int i; ll* lst = ll_new(32); // Fill the list with L[i] = i^2 for (i=0; i<10000; i++) ll_append(lst, i*i); //ll_print(lst); CuAssertIntEquals(tc, 0, ll_sorted_contains(lst, -1)); CuAssertIntEquals(tc, 1, ll_sorted_contains(lst, 0)); CuAssertIntEquals(tc, 1, ll_sorted_contains(lst, 1)); CuAssertIntEquals(tc, 1, ll_sorted_contains(lst, 4)); // 961 = 31^2 CuAssertIntEquals(tc, 0, ll_sorted_contains(lst, 960)); CuAssertIntEquals(tc, 1, ll_sorted_contains(lst, 961)); CuAssertIntEquals(tc, 0, ll_sorted_contains(lst, 962)); // 1024 = 32^2 CuAssertIntEquals(tc, 0, ll_sorted_contains(lst, 1023)); CuAssertIntEquals(tc, 1, ll_sorted_contains(lst, 1024)); CuAssertIntEquals(tc, 0, ll_sorted_contains(lst, 1025)); }
BIN_LIST binning(int *tumor_1bp_bin, int n_tumor, int *normal_1bp_bin, int n_normal,int bin_size) { int i,nrow,max_pos,min_pos; int start,end ,i_tum, i_norm; double tumorcnt, normalcnt,freq,total, N_tumor, N_normal; BIN_LIST bins = ll_new(); max_pos = (tumor_1bp_bin[2*(n_tumor-1)]>normal_1bp_bin[2*(n_normal-1)])? tumor_1bp_bin[2*(n_tumor-1)]: normal_1bp_bin[2*(n_normal-1)]; min_pos = (tumor_1bp_bin[0]<normal_1bp_bin[0])?tumor_1bp_bin[0]:normal_1bp_bin[0]; nrow = (max_pos-min_pos+1)/bin_size+10; N_tumor = 0.0; N_normal = 0.0; i_tum = 0; i_norm = 0; start = min_pos - (min_pos-1)%bin_size;/*the start position of the left most bin*/ end = start + bin_size -1; for(i=0;i<nrow;i++) { tumorcnt = 0.0; normalcnt = 0.0; while(tumor_1bp_bin[2*i_tum]<=end&&i_tum<n_tumor) { tumorcnt += tumor_1bp_bin[2*i_tum+1]; i_tum++; } while(normal_1bp_bin[2*i_norm]<=end&&i_norm<n_normal) { normalcnt += normal_1bp_bin[2*i_norm+1]; i_norm++; } total = tumorcnt + normalcnt; freq = tumorcnt/total; if(total>0.0) ll_append(bins, bin_new(tumorcnt, total, freq, start, end)); N_tumor += tumorcnt; N_normal += normalcnt; start += bin_size; end = start + bin_size -1; } set_totalreadcount(N_tumor,N_normal); return bins; }
int main() { log_info("Creating a linked list."); LinkedList* list = ll_new(); check(list->first == NULL, "List was not correctly initialised."); check(list->length == 0, "List should not have any elements."); log_info("Adding an element to the list."); int v = 1337; int* vpointer = malloc(sizeof(int)); *vpointer = v; ll_prepend(list, vpointer); check(list->length == 1, "Length increment failed"); check(list->first != NULL, "Append failed"); check(list->first->data == vpointer, "Bad address"); log_info("The address of list->first->data %p", list->first->data); check(*((int*) list->first->data) == v, "Bad value"); log_info("The value is %d as expected", *((int*) list->first->data)); log_info("Adding another element."); v = 1338; int* another = malloc(sizeof(int)); *another = v; ll_prepend(list, another); check(list->length == 2, "Length increment failed"); check(*((int*) list->first->data) == v, "List increment screwed up"); log_info("Checking list[0]."); check(*((int*) ll_get(list, 0)) == v, "First element does not match what was last prepended."); log_info("Checking list[1]."); check(*((int*) ll_get(list, 1)) == 1337, "First element does not match what was first prepended."); log_info("Freeing the linked list."); ll_free(list); return 0; error: return 1; }
pll_entry lexer_parse_brwords(pll_entry tokens, plinkedlist* list) { *list = ll_new(); ptoken t = GETTKN(tokens); char even = 0; CHECK_TOKEN(t, TOKEN_BRSTART); tokens = NEXTTKN(tokens); t = GETTKN(tokens); while(t->base.type != TOKEN_BREND) { if(!even) { CHECK_TOKEN(t, TOKEN_WORD); ll_push(*list, t->string); } else CHECK_TOKEN(t, TOKEN_COMMA); even = !even; tokens = NEXTTKN(tokens); t = GETTKN(tokens); } return tokens; }
int main(int argc, char **argv) { int n_tmor,n_nml,ncol,nbins; double *tumor, *normal; SRM_binning args; BIN_LIST bins = ll_new(); args = option_assign(argc,argv); if(args.inbin_file==NULL){ /*input is not binned data*/ tumor = read_table(args.in_tmor,&n_tmor,&ncol,-1,0); if(tumor==NULL) { fprintf(stderr,"Warning: the file %s is empty.\n",args.tumor_file);exit(1);} if(ncol!=1) {fprintf(stderr,"Error: tumor file has multiple columns.\n"); exit(1);} fprintf(stderr,"%d tumor reads loaded\n",n_tmor); normal = read_table(args.in_nml,&n_nml,&ncol,-1,0); if(normal==NULL) { fprintf(stderr,"Warning: the file %s is empty.\n",args.normal_file);exit(1);} if(ncol!=1) { fprintf(stderr,"Error: normal file has multiple columns.\n"); exit(1);} fprintf(stderr,"%d normal reads loaded\n",n_nml); if(args.fdr==1&&args.resampling==1){ qsort(tumor,n_tmor,sizeof(double),cmpdouble); fprintf(stderr,"sorted %d case reads\n",n_tmor); qsort(normal,n_nml,sizeof(double),cmpdouble); fprintf(stderr,"sorted %d control reads.\n",n_nml); check_read(tumor,n_tmor); check_read(normal,n_nml); fprintf(stderr,"Start resampling\n"); bic_seq_resample(tumor,n_tmor,normal,n_nml,args); free(tumor);tumor=NULL; free(normal);normal = NULL; } else{ fprintf(stderr,"Binning\n"); bins = sort_rms_binning(tumor,n_tmor,normal,n_nml,args.bin_size,&nbins,args.win_size,args.quantile,args.multple,args.outlier,args.tumor_file,args.normal_file); /*sort, remove singular positions and bin*/ if(args.binout_file!=NULL){ fprintf(stderr,"Reporting Binned data\n"); BIN_LIST_print(bins, args.outbin); } if(args.fdr!=1){ set_BinList(bins); fprintf(stderr,"Merging\n"); if(args.autoselect_lambda!=1){ bic_seq(args.paired); }else{ bic_seq_auto(ll_length(bins),args.FP, args.paired); } bins = get_BinList(); BIN_LIST_print(bins, args.output); ll_dealloc(bins); }else{ SEG_PERMUTE segs = NULL; segs = bic_seq_perm(bins, args.tumor_freq, args.FP,args.B ,args.autoselect_lambda); print_SEG_PERMUTE(segs,args.output); SEG_PERMUTE_destroy(segs); segs = NULL; } } }else{ double N_total=0.0, N_tumor=0.0,freq; int start, end, tumor, total; while (fscanf(args.inbin, "%d %d %lf %d %d", &tumor, &total, &freq, &start, &end) != EOF) { ll_append(bins, bin_new(tumor, total, freq, start, end)); N_total += total; N_tumor += tumor; } set_totalreadcount(N_tumor,N_total-N_tumor); if(args.fdr!=1){ set_BinList(bins); fprintf(stderr,"Merging\n"); if(args.autoselect_lambda!=1){ bic_seq(args.paired); //bic_seq(0); }else{ bic_seq_auto(ll_length(bins),args.FP, args.paired); //bic_seq_auto(ll_length(bins),args.FP, 0); } bins = get_BinList(); BIN_LIST_print(bins, args.output); ll_dealloc(bins); }else{ SEG_PERMUTE segs = NULL; segs = bic_seq_perm(bins, args.tumor_freq, args.FP,args.B ,args.autoselect_lambda); print_SEG_PERMUTE(segs,args.output); SEG_PERMUTE_destroy(segs); segs = NULL; } } return 0; }
#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "ll.h" #include "rbtree.h" #include "bin.h" #include <R.h> #include <Rinternals.h> #include <R_ext/Rdynload.h> double N; double lambda = 1.0; BIN_LIST bins = ll_new(); BIN * bin_new(int tumor, int total, double freq, int start, int end) { BIN *nb = malloc(sizeof(BIN)); if (nb == NULL) { printf("bin_new: malloc: %s\n", strerror(errno)); exit(1); } nb->tumor = tumor; nb->total = total; nb->freq = freq; nb->start = start;
Segment segment_new(Worm worm) { Segment retval = malloc(sizeof(struct _Segment)); Node iterator = worm->front; Node prev = NULL; int i = 0; int xdirection = -1; int ydirection = 0; while (iterator != NULL) { Segment last = (Segment) iterator->data; if (prev != NULL) { Segment prevseg = (Segment) prev->data; if (prevseg->location->y > last->location->y) { ydirection = -1; } else { ydirection = 1; } } if (iterator->next == NULL) { iterator->next = ll_new(retval); int remaining = (worm->size - i); // Is there enough space? if (last->location->x > 1) { retval->location = location_new(last->location->x + xdirection, last->location->y); } else if (last->location->x < remaining + 1) { // Need more room. if (ydirection == 0) { // Have no direction if (last->location->y + 1> remaining) { ydirection = -1; } else { ydirection = 1; } } retval->location = location_new(last->location->x, last->location->y + ydirection); } debug("Created segment at %d,%d", retval->location->x, retval->location->y); move(retval->location->y, retval->location->x); addch('*'); refresh(); usleep(PAUSE); return retval; } prev = iterator; iterator = iterator->next; i++; } if (worm->front == NULL) { worm->front = ll_new(retval); retval->location = location_rand(worm->grid); } debug("Created segment at %d,%d", retval->location->x, retval->location->y); mvaddch(retval->location->y, retval->location->x, '*'); refresh(); usleep(PAUSE); return retval; }
static statement *get_expression(parse_source *source, int *indent) { parse_token token = get_mandatory_token(source); if(equals_string(token.data, "{")) { statement *expression = new(expression); expression->type = BLOCK; expression->children = ll_new(); expression->data = new_slice(""); int finished = *indent; *indent += 1; while(*indent != finished) { statement *state = get_expression(source, indent); if(state != NULL) ll_add_last(expression->children, state); } return expression; } else if(equals_string(token.data, "}")) { *indent -= 1; return NULL; } else if(equals_string(token.data, "if") || equals_string(token.data, "while") || equals_string(token.data, "for")) { statement *expression = new(expression); if(equals_string(token.data, "if")) expression->type = IF; else if(equals_string(token.data, "while")) expression->type = WHILE; else if(equals_string(token.data, "for")) expression->type = FOR; expression->children = ll_new(); expression->data = new_slice(""); ll_add_last(expression->children, get_expression(source, indent)); //Add the header if(expression->type == FOR) { ll_add_last(expression->children, get_expression(source, indent)); //Add the header ll_add_last(expression->children, get_expression(source, indent)); //Add the header } ll_add_last(expression->children, get_expression(source, indent)); //Add the body if(expression->type == IF) { parse_token next = peek_mandatory_token(source); if(equals_string(next.data, "else")) { get_mandatory_token(source); statement *elseState = new(elseState); elseState->type = ELSE; elseState->children = ll_new(); elseState->data = new_slice(""); ll_add_last(expression->children, elseState); ll_add_first(elseState->children, get_expression(source, indent)); } } return expression; } else if(equals_string(token.data, "break") || equals_string(token.data, "continue")) { statement *expression = new(expression); expression->type = equals_string(token.data, "break") ? BREAK : CONTINUE; expression->data = new_slice(""); expression->children = NULL; parse_token next = get_mandatory_token(source); if(!equals_string(next.data, ";")) semantic_error("Expected a semicolon after a break or continue", next.origin); return expression; } else if(equals_string(token.data, "return")) { statement *expression = new(expression); expression->type = RETURN; expression->data = new_slice(""); expression->children = ll_new(); ll_add_last(expression->children, get_expression(source, indent)); return expression; } else { linked_list *accumulator = ll_new(); parse_token next = token; while(true) { parse_token *allocated = new(allocated); *allocated = token; ll_add_last(accumulator, allocated); next = peek_mandatory_token(source); if(equals_string(next.data, "{") || equals_string(next.data, "}")) break; if(equals_string(next.data, ";")) { get_mandatory_token(source); break; } token = get_mandatory_token(source); } statement *expression = parse_simple_expression(accumulator); ll_delete_all(accumulator); return expression; } }
plinkedlist lexer_parse(char* source) { plinkedlist tokens = ll_new(); char inSlComment = 0, inMlComment = 0; int l, currline = 1; char* curr, *start; while(*curr!='\0') { if(*curr=='\n') { currline++; if(inSlComment) //single inSlComment = !inSlComment; } else if(isspace(*curr)) { /* curr++; continue; */ //<-- same as leaving execution to go on (jumping through ifelses has the same effect) } else if(*curr=='/') { if(!inSlComment && !inMlComment) { if(curr[1]=='/') inSlComment = !inSlComment; else if(curr[1]=='*') inMlComment = !inMlComment; } } else if(*curr=='*' && !inSlComment && inMlComment) { if(curr[1]=='/') inMlComment = !inMlComment; } else if(inSlComment || inMlComment) { /* curr++; continue; */ //<-- same as leaving execution to go on (jumping through ifelses has the same effect) } else if(isdigit(*curr)) { start = curr; while(isdigit(*++curr)) ; /* to point on the last character of token */ curr--; l = (int)(curr - start+1); start = (char*)malloc(l+1); strncpy(start, curr-l+1, l); start[l] = '\0'; ll_push(tokens, lexer_token_create(TOKEN_NUMBER, start, currline)); } else if(*curr=='"') { start = ++curr; /* skip first doublequote */; char slashactive = 0; while(*curr!='\0' && !(*curr=='"' && !slashactive)) { if(*curr=='\\') slashactive = !slashactive; else if(slashactive) slashactive = 0; if(*curr=='\n') currline++; curr++; } /* curr pointing on the last character of token */ l = (int)(curr - start +1); start = (char*)malloc(l+1); strncpy(start, curr-l+1, l); start[l] = '\0'; ll_push(tokens, lexer_token_create(TOKEN_STRING, start, currline)); } else if(isalpha(*curr) || *curr=='_') { /* nothing found here, it's not a constant token */ /* could it be an identifier? */ start = curr; do { curr++; } while(isalnum(*curr) || *curr=='_'); l = (int)(curr - start); start = (char*)malloc(l+1); strncpy(start, curr-l, l); start[l] = '\0'; /* to ensure curr points on characters last token */ curr--; int i; for(i = 0;keywords[i].base.type != TOKEN_EOL;i++) if(*start==*keywords[i].string) /* if the first character equals, check the full string */ if(strcmp(start, keywords[i].string) == 0) { ll_push(tokens, lexer_token_copy(&keywords[i], currline)); /* (we don't need the local copy of the string anymore) */ free(start); break; } /* if they aren't equal, continue */ /* if the first character isn't equal, continue searching */ /* if this is not a keyword, it's a word (indentfier) */ if(keywords[i].base.type == TOKEN_EOL) ll_push(tokens, lexer_token_create(TOKEN_WORD, start, currline)); } else { int i; for(i = 0;operators[i].base.type != TOKEN_EOL;i++) if(strncmp(operators[i].string, curr, strlen(operators[i].string)) == 0) { ll_push(tokens, lexer_token_copy(&operators[i], currline)); curr += strlen(operators[i].string)-1; break; } if(operators[i].base.type == TOKEN_EOL) FATAL("Invalid token '%c' found on line %d", *curr, currline); } curr++; } /* mark the EOF */ ll_push(tokens, lexer_token_create(TOKEN_EOF, NULL, currline)); /* return the linked list with tokens */ return tokens; }
abLayer::abLayer(lcd_image_t _background) { sprites = ll_new(); background = _background; hasDrawnOnce = false; toEraseCount = 0; }
static statement *parse_simple_expression(linked_list *tokens) { while(equals_string(((parse_token*)ll_get_first(tokens))->data, "(") && equals_string(((parse_token*)ll_get_last(tokens))->data, ")")) { ll_remove_first(tokens); ll_remove_last(tokens); } int size = ll_size(tokens); switch(size) { case 0: return NULL; case 1: return parse_single_token(tokens); default: { if(size == 2) { parse_token *token = ll_get_first(tokens); bool isStack; if((isStack = equals_string(token->data, "new")) || equals_string(token->data, "newref")) { statement *expression = new(expression); expression->children = ll_new(); expression->type = isStack ? STACK_INIT : HEAP_INIT; linked_list *name = ll_duplicate(tokens); ll_remove_first(name); ll_add_first(expression->children, parse_simple_expression(name)); return expression; } } int paren_level = 1; linked_iter iterator = ll_iter_head(tokens); bool is_index = true, is_call = true; ll_iter_next(&iterator); parse_token *second = ll_iter_next(&iterator); if(equals_string(second->data, "(")) { is_index = false; } else if(equals_string(second->data, "[")) { is_call = false; } else { is_index = is_call = false; } while((is_index || is_call) && ll_iter_has_next(&iterator)) { parse_token *token = ll_iter_next(&iterator); if(equals_string(token->data, "(") || equals_string(token->data, "[")) { paren_level += 1; } else if(paren_level == 0) { is_index = false; is_call = false; } else if(equals_string(token->data, ")") || equals_string(token->data, "]")) { paren_level -= 1; } } if(is_index) { return parse_array_index(tokens); } else if(is_call) { return parse_func_call(tokens); } linked_list *operator = get_node(); linked_iter level = ll_iter_head(operator); while(ll_iter_has_next(&level)) { int paren_level = 0; linked_list *currentLevel = ll_iter_next(&level); linked_iter iterator = ll_iter_head(tokens); for(parse_token *current = ll_iter_next(&iterator); ll_iter_has_next(&iterator); current = ll_iter_next(&iterator)) { char currentChar = current->data.data[0]; if(currentChar == '(') { paren_level += 1; } else if(currentChar == ')') { paren_level -= 1; } if(paren_level != 0) continue; linked_iter innerMost = ll_iter_head(currentLevel); while(ll_iter_has_next(&innerMost)) { operator_node *currentOperator = ll_iter_next(&innerMost); if(equals_string(current->data, currentOperator->data)) { if(!is_unary_operator(new_slice(currentOperator->data))) { linked_list *op1 = ll_duplicate(tokens); while(ll_get_last(op1) != current) ll_remove_last(op1); ll_remove_last(op1); linked_list *op2 = tokens; while(ll_get_first(op2) != current) ll_remove_first(op2); ll_remove_first(op2); statement *expression = new(expression); expression->data = new_slice(""); expression->children = ll_new(); expression->type = currentOperator->operatorType; statement *op1_exp = parse_simple_expression(op1); statement *op2_exp = parse_simple_expression(op2); ll_add_last(expression->children, op1_exp); ll_add_last(expression->children, op2_exp); return expression; } else { statement *expression = new(expression); expression->data = new_slice(currentOperator->data); expression->type = currentOperator->operatorType; linked_list *rest = ll_duplicate(tokens); ll_remove_first(rest); expression->children = ll_new(); ll_add_first(expression->children, parse_simple_expression(rest)); return expression; } } } } } return NULL; } } }