struct Token *function_not(struct Token *statement, struct List *scope){ struct Token *exp; exp = statement->list->tokens[1]; struct Token *result = function_execute(exp,scope); if(result->value > 0){ return token_create(T_NUMBER,0); }else{ return token_create(T_NUMBER,1);; } }
struct List *list_create(){ struct List *list = malloc(sizeof(struct List)); list->tokens = malloc(sizeof(struct Token *)); list->tokens[0] = token_create('#',0); list->length = 1; list->type = 0; list_remove(list,0); return list; }
struct Token *function_if(struct Token *statement, struct List *scope){ struct Token *exp, *stm; exp = statement->list->tokens[1]; stm = statement->list->tokens[2]; struct Token *result = function_execute(exp,scope); if(result->value > 0){ function_execute_list(stm->list,stm->list); } return token_create(T_NUMBER,0); }
struct Token *function_execute(struct Token *statement, struct List *scope){ int header = statement->list->tokens[0]->type; if( token_is_operator(header) ) return function_operator(statement,scope); if(header == T_PRINT) return function_print(statement,scope); if(header == T_IF) return function_if(statement,scope); if(header == T_EXPRESSION) return function_expression(statement,scope); if(header == T_STRING) return statement->list->tokens[1]; if(header == T_EQUALS) return function_assignment(statement,scope); if(header == T_LOOKUP) return function_lookup(statement,scope); if(header == T_NOT) return function_not(statement,scope); printf("(ERROR:function_execute) Statement was not a valid function.\n"); return token_create(T_NUMBER,0); }
struct Token *function_operator(struct Token *statement, struct List *scope){ struct Token *left, *right, *op; op = statement->list->tokens[0]; left = statement->list->tokens[1]; right = statement->list->tokens[2]; if( left->type != T_NUMBER ) left = function_execute(left,scope); if( right->type != T_NUMBER ) right = function_execute(right,scope); int result = 0; if( op->type == T_ADD) result = left->value + right->value; if( op->type == T_SUBTRACT) result = left->value - right->value; if( op->type == T_MULTIPLY) result = left->value * right->value; if( op->type == T_DIVIDE) result = left->value / right->value; return token_create(T_NUMBER,result); }
struct Token *function_lookup(struct Token *statement, struct List *scope){ struct Token *word = token_create(T_LIST,LIST_FUNCTION); struct Token *arg = statement->list->tokens[1]; char *name; if( arg->value == T_LIST ){ name = function_execute(arg, scope)->string; }else if (arg->type == T_STRING){ name = arg->string; }else{ printf("(ERROR:function_lookup) Invalid lookup type. "); } // For each statement int i; for(i=0; i<scope->length; i++){ struct Token *func = scope->tokens[i]; struct Token *header = func->list->tokens[0]; // Grab the header of said function // If statement is an assignment if( header->type == T_EQUALS ){ struct Token *fname = func->list->tokens[1]; struct Token *fvalue = func->list->tokens[2]; // If the function name matches the lookup name if( strcmp(fname->string,name) == 0 ){ return function_execute(fvalue,scope); } } } printf("(ERROR:function_lookup) '%s' not found in scope.\n", name); return word; }
// takes n arguments struct Token *function_print(struct Token *statement, struct List *scope){ // For each argument, evaluate and print int i; for(i=1; i<statement->list->length; i++){ struct Token *arg = statement->list->tokens[i]; if(arg->type == T_LIST && arg->value == LIST_FUNCTION){ //list_print(exp->list); struct Token *result = function_execute(arg,scope); if( result->type == T_STRING){ printf("->'%s'\n",result->string); }else if ( result->type == T_NUMBER ){ printf("->%d\n",result->value); }else{ printf("(ERROR:function_print) Could not print type '%s'.\n",parse_type_to_word(result->type)); } }else if (arg->type == T_STRING){ printf("(ERROR:function_print) Invalid argument at '%d'.\n",i-1); } } return token_create(T_NUMBER,0); }
struct Token *function_assignment(struct Token *statement, struct List *scope){ return token_create(T_NUMBER,0); }
/* * Command-line front end for compiler. */ int main(int argc, char **argv) { int action; int arg; buffer_t *in_buffer; buffer_t *out_buffer; int is_done; parser_t *parser; lexer_t *lexer; token_t *token; /* Set default settings. */ action = ACT_TRANS; in_buffer = buffer_create(stdin); out_buffer = buffer_create(stdout); /* Parse command-line arguments. */ for (arg = 1; arg < argc; arg++) { if ((strcmp(argv[arg], "--help") == 0) || (strcmp(argv[arg], "-h") == 0)) { action = ACT_USAGE; } else if ((strcmp(argv[arg], "--lex") == 0) && (action <= ACT_LEX)) { action = ACT_LEX; } else if ((strcmp(argv[arg], "--parse") == 0) && (action <= ACT_PARSE)) { action = ACT_PARSE; } else if ((strcmp(argv[arg], "--translate") == 0) && (action <= ACT_TRANS)) { action = ACT_TRANS; } else { fprintf(stderr, "Invalid argument: %s\n", argv[arg]); /* Stop parsing command-line. */ arg = argc; action = ACT_USAGE; } } /* Take action. */ if (action == ACT_USAGE) { printf( "Usage: compiler [option...]\n" "\n" " Options:\n" "\n" " -h, --help Display this help text.\n" " --lex Run the lexer.\n" " --parse Run the parser. (Calls the lexer.)\n" " --translate Run the translator. (Calls the parser.)\n" ); } else if (action == ACT_LEX) { is_done = 0; lexer = lexer_create(in_buffer); token = token_create(); while (!is_done) { lexer_lex(lexer, token); token_print(token, stdout); printf("\n"); if (token_get_class(token) == T_EOF) is_done = 1; } token_destroy(token); lexer_destroy(lexer); return EXIT_SUCCESS; } else if (action == ACT_PARSE) { parser = parser_create(in_buffer); parser_parse(parser); parser_destroy(parser); return EXIT_SUCCESS; } else if (action == ACT_TRANS) { parser = parser_create(in_buffer); parser_parse(parser); translator_translate(parser_get_tree(parser)); parser_destroy(parser); return EXIT_SUCCESS; } return EXIT_SUCCESS; }
struct linked_list *ctache_lex(const char *str, size_t str_len, const char *delim_begin, const char *delim_end) { struct linked_list *tokens = linked_list_create(); if (tokens == NULL) { fprintf(stderr, "ctache_lex(): Cannot create tokens list\n"); return NULL; } size_t delim_begin_len = strlen(delim_begin); size_t delim_end_len = strlen(delim_end); size_t strval_len = 0; size_t strval_bufsize = STRVAL_INITIAL_BUFSIZE; char *strval = malloc(strval_bufsize); memset(strval, 0, strval_bufsize); int row = 0; int col = 0; struct ctache_token *tok = NULL; int ch; unsigned int i; for (i = 0; i < str_len; i++) { ch = str[i]; if (ch == delim_begin[0]) { if (i + delim_begin_len + 1 < str_len) { if (strncmp(str + i, delim_begin, delim_begin_len) == 0 && str[i + delim_begin_len] == '#') { if (strval_len > 0) { tok = token_create(CTACHE_TOK_STRING, strdup(strval), row, col); strval_len = 0; memset(strval, 0, strval_bufsize); linked_list_append(tokens, tok); } tok = token_create(CTACHE_TOK_SECTION_TAG_START, NULL, row, col); linked_list_append(tokens, tok); i += delim_begin_len; col += delim_begin_len; } else if (strncmp(str + i, delim_begin, delim_begin_len) == 0 && str[i + delim_begin_len] == '/') { if (strval_len > 0) { tok = token_create(CTACHE_TOK_STRING, strdup(strval), row, col); strval_len = 0; linked_list_append(tokens, tok); memset(strval, 0, strval_bufsize); } tok = token_create(CTACHE_TOK_CLOSE_TAG_START, NULL, row, col); linked_list_append(tokens, tok); i += delim_begin_len; col += delim_begin_len; } else if (strncmp(str + i, delim_begin, delim_begin_len) == 0 && str[i + delim_begin_len] == '>') { if (strval_len > 0) { tok = token_create(CTACHE_TOK_STRING, strdup(strval), row, col); strval_len = 0; linked_list_append(tokens, tok); memset(strval, 0, strval_bufsize); } tok = token_create(CTACHE_TOK_PARTIAL_TAG, NULL, row, col); linked_list_append(tokens, tok); i += delim_begin_len; } else if (strncmp(str + i, delim_begin, delim_begin_len) == 0 && (str[i + delim_begin_len] == '&' || str[i + delim_begin_len] == delim_begin[0])) { if (strval_len > 0) { tok = token_create(CTACHE_TOK_STRING, strdup(strval), row, col); strval_len = 0; linked_list_append(tokens, tok); memset(strval, 0, strval_bufsize); } tok = token_create(CTACHE_TOK_UNESC_VALUE_TAG_START, NULL, row, col); linked_list_append(tokens, tok); i += delim_begin_len; col += delim_begin_len; } else if (strncmp(str + i, delim_begin, delim_begin_len) == 0) { if (strval_len > 0) { tok = token_create(CTACHE_TOK_STRING, strdup(strval), row, col); strval_len = 0; linked_list_append(tokens, tok); memset(strval, 0, strval_bufsize); } tok = token_create(CTACHE_TOK_VALUE_TAG_START, NULL, row, col); linked_list_append(tokens, tok); i += delim_begin_len - 1; col += delim_begin_len - 1; } else { add_char_to_strval(&strval, &strval_bufsize, &strval_len, ch); col += delim_begin_len - 1; } } else { add_char_to_strval(&strval, &strval_bufsize, &strval_len, ch); col += delim_begin_len - 1; } } else if (ch == delim_end[0]) { if (strncmp(str + i, delim_end, delim_end_len) == 0 && str[i + delim_end_len] == delim_end[0]) { if (strval_len > 0) { tok = token_create(CTACHE_TOK_STRING, strdup(strval), row, col); strval_len = 0; linked_list_append(tokens, tok); memset(strval, 0, strval_bufsize); } tok = token_create(CTACHE_TOK_TAG_END, NULL, row, col); linked_list_append(tokens, tok); i += delim_end_len; col += delim_end_len; } else if (strncmp(str + i, delim_end, delim_end_len) == 0) { if (strval_len > 0) { tok = token_create(CTACHE_TOK_STRING, strdup(strval), row, col); strval_len = 0; linked_list_append(tokens, tok); memset(strval, 0, strval_bufsize); } tok = token_create(CTACHE_TOK_TAG_END, NULL, row, col); linked_list_append(tokens, tok); i += delim_end_len - 1; col += delim_end_len - 1; } else { add_char_to_strval(&strval, &strval_bufsize, &strval_len, ch); col += delim_end_len - 1; } } else if (ch == '\n') { add_char_to_strval(&strval, &strval_bufsize, &strval_len, ch); row++; col = 0; } else { add_char_to_strval(&strval, &strval_bufsize, &strval_len, ch); col += 1; } } if (strval_len > 0) { tok = token_create(CTACHE_TOK_STRING, strdup(strval), row, col); linked_list_append(tokens, tok); col += strval_len; } free(strval); strval = NULL; /* Add a final EOI token */ tok = token_create(CTACHE_TOK_EOI, NULL, row, col); linked_list_append(tokens, tok); return tokens; }