struct lexer *lexer_create_substitution(struct lexer *lx, struct token *t) { char *substitution = NULL; if(lx->environment) { substitution = dag_variable_lookup_string(t->lexeme, lx->environment); } struct lexer *lx_s; if(!substitution) { fatal("Variable %s has not yet been defined at line % " PRId64 ".\n", t->lexeme, lx->line_number); substitution = xxstrdup(""); } lx_s = lexer_create(STRING, substitution, lx->line_number, lx->column_number); lx_s->depth = lx->depth + 1; if(lx_s->depth > MAX_SUBSTITUTION_DEPTH) lexer_report_error(lx, "More than %d recursive subsitutions attempted.\n", MAX_SUBSTITUTION_DEPTH); free(substitution); return lx_s; }
int run_repl(context* ctx) { parser_state* ps = calloc(sizeof(parser_state), 1); ps->die_on_error = 0; ps->error.max = 20; for(unsigned line = 1; ; ++line) { char* input = readline(">> "); if(input == NULL) break; add_history(input); char* ret = malloc(strlen(input) + 2); strcpy(ret, input); strcat(ret, "\n"); free(input); reader r; string_reader_create(&r, ret); lexer_state* ls = calloc(sizeof(lexer_state), 1); lexer_create(ls, &r); ps->ls = ls; ps->ls->linenum = line; ps->t = lexer_next_token(ps->ls); expression_node* program = parse_program(ps); if(program && program->node.block) { for(struct expression_list* expr = program->node.block->list; expr; expr = expr->next) { expression_node* eval = expression_node_evaluate(expr->expression, ctx); char* str = expression_node_inspect(eval); printf("==> %s\n", str); free(str); expression_node_destroy(eval); } expression_node_destroy(program); free(r.fn_data); lexer_destroy(ls); free(ls); free(ret); } } free(ps); return 0; }
int interpret_program(tvm_program_t* p, char* filename, tvm_memory_t* pMemory) { int i; FILE* pFile = NULL; int source_length = 0; char* source = NULL; tvm_lexer_t* lexer = NULL; /* Attempt to open the file. If the file cannot be opened, try once more. */ if(filename) for(i = 0; i < 2; i++) if(!pFile) pFile = tvm_fopen(filename, ".vm", "r"); if(!pFile) { printf("File was not found, or does not exist. Unable to interpret.\n"); return 1; } source_length = tvm_flength(pFile); source = malloc(source_length); tvm_fcopy(source, source_length, pFile); lexer = lexer_create(); lex(lexer, source); free(source); fclose(pFile); if(parse_labels(p, (const char***)lexer->tokens) != 0) return 1; for(i = 0; lexer->tokens[i]; i++) { p->instr = (int*)realloc(p->instr, sizeof(int) * (i + 2)); p->instr[i] = 0; p->args = (int***)realloc(p->args, sizeof(int**) * (i + 2)); p->args[i] = (int**)calloc(MAX_ARGS, sizeof(int*)); parse_instruction(p, (const char**)lexer->tokens[i], pMemory); } lexer_destroy(lexer); p->args[i] = NULL; p->instr[i] = -0x1; return 0; }
struct compiler *compiler_create(const char* input, const char *filename) { struct compiler* result = malloc(sizeof(struct compiler)); result->filename = filename; result->err_count = 0; result->current_block = 0; allocator_init(&result->allocator); lexer_create(result, input); return result; }
static int dag_parse(struct dag *d, FILE *stream) { struct lexer *bk = lexer_create(STREAM, stream, 1, 1); bk->d = d; bk->stream = stream; bk->category = dag_task_category_lookup_or_create(d, "default"); struct dag_variable_lookup_set s = { d, NULL, NULL, NULL }; bk->environment = &s; struct token *t; while((t = lexer_peek_next_token(bk))) { s.category = bk->category; s.node = NULL; s.table = NULL; switch (t->type) { case TOKEN_NEWLINE: case TOKEN_SPACE: /* Skip newlines, spaces at top level. */ lexer_free_token(lexer_next_token(bk)); break; case TOKEN_SYNTAX: dag_parse_syntax(bk); break; case TOKEN_FILES: dag_parse_node(bk); break; case TOKEN_VARIABLE: dag_parse_variable(bk, NULL); break; default: lexer_report_error(bk, "Unexpected token. Expected one of NEWLINE, SPACE, SYNTAX, FILES, or VARIABLE, but got: %s\n:", lexer_print_token(t)); break; } } dag_close_over_environment(d); dag_compile_ancestors(d); free(bk); return 1; }
int run_file(const char* filename, context* ctx) { reader r; lexer_state* ls = calloc(sizeof(lexer_state), 1); parser_state* ps = calloc(sizeof(parser_state), 1); FILE* fp = fopen(filename, "r"); if(!fp) { printf("Error: can't open file '%s'\n", filename); return 1; } file_reader_create(&r, fp); lexer_create(ls, &r); ps->ls = ls; ps->die_on_error = 0; ps->error.max = 20; ps->t = lexer_next_token(ps->ls); expression_node* program = parse_program(ps); expression_node* eval = expression_node_evaluate(program, ctx); expression_node_destroy(eval); expression_node_destroy(program); lexer_destroy(ls); free(ls); free(ps); free(r.fn_data); fclose(fp); return 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; }