char* multiply(char* n1, char* n2) { int n1n = strlen(n1), n2n = strlen(n2); int* rec = (int*) malloc(sizeof(int) * (n1n + n2n - 1)); int i = 0, i1 = 0, i2 = 0, val = 0; pll l = (pll) malloc(sizeof(sll)); l->first = NULL; l->last = NULL; l->size = 0; for (i = 0; i < n1n + n2n - 1; i ++) rec[i] = 0; for (i1 = 0; i1 < n1n; i1 ++) { for (i2 = 0; i2 < n2n; i2 ++) { rec[i1 + i2] += (*(n1 + i1) - '0') * (*(n2 + i2) - '0'); } } for (val = 0, i = n1n + n2n - 2; i > -1; i --) { val += rec[i]; ll_add_first(l, (char)('0' + val % 10)); val = val / 10; } while (val != 0) { ll_add_first(l, (char)('0' + val % 10)); val = val / 10; } while (l->first != l->last && l->first->val == '0') ll_remove_first(l); ll_add_last(l, '\0'); free(rec); return ll_convert_to_array_free_l(l); }
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 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; }
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; } } }
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; } }
int main(int argc, char **argv) { int c = 0; llist_t* list = 0; node_t* aux = 0; list = ll_create(); ll_initialize(list, free, compare_int_data); /* 0...9 */ for(; c < 10; c++) ll_add_last(list, create_node( create_int_data(c) ) ); /* 10 0...9 */ ll_add_first(list, create_node( create_int_data(c) ) ); /* 11 10 0...9 */ ll_add_first(list, create_node( create_int_data(++c) ) ); /* 11 10 12 0...9 */ ll_add_before(list, list->first->next->next, create_node( create_int_data(++c) ) ); /* 11 10 12 0...8 13 9 */ ll_add_after(list, list->last->prev, create_node( create_int_data(++c) )); /* 11 10 12 0...8 13 14 9 */ ll_add_after(list, list->last->prev, create_node( create_int_data(++c) )); /* 11 12 0...8 13 14 9 */ ll_remove(list, list->first->next, DESTROYNODE ); /* 11 12 0...8 13 14 */ ll_remove(list, list->last, DESTROYNODE); /* 12 0...8 13 14 */ ll_remove(list, list->first, DESTROYNODE); /* to test "NOTDESTROY" option*/ aux = list->last->prev; /* 12 0...8 14 */ ll_remove(list, list->last->prev, NOTDESTROY); printf("\n"); /* Forward: 12 0...8 14 */ ll_traverse(list, print_int_data, FORWARDTRAVERSE); printf("\n"); /* Backward: 14 8...0 12 */ ll_traverse(list, print_int_data, BACKWARDTRAVERSE); printf("\n\n"); /* Destroy node "13"*/ free_node(aux, list->free_data); printf("\n"); /* Deleted node, is not found*/ int a = 10; aux = ll_search_node(list, &a); if(aux != NULL) printf("NODE: %p DATA: %d\n", aux ,*(int*)DATA(aux)); a = 4; aux = ll_search_node(list, &a); if(aux != NULL) printf("NODE: %p DATA: %d\n", aux ,*(int*)DATA(aux)); ll_free(list); list = 0; return EXIT_SUCCESS; }