#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char* const* argv) { ENTER; struct cmdln_flags* flags = new_cmdln_flags(argc, argv); struct booleans* booleans = new_booleans(); struct color_factory* cfactory = new_color_factory(); struct environment* environment = new_environment( /* fallback: */ NULL); environment_declare_builtins( /* this: */ environment, /* booleans: */ booleans); if (flags->read_init_file) { dpvs(flags->custom_init_path); handle_init_file(&environment, booleans, flags->custom_init_path); } switch (flags->input_kind) { case ik_string: { TODO; #if 0 assert(flags->input_string); struct istream* stream = new_string_istream( /* read-only text: */ (const uint8_t*) flags->input_string); struct string* filename = new_string( /* data: */ (const uint8_t*) "", /* len: */ (size_t) -1); struct position* position = new_position( /* filename: */ filename, /* line number: */ 1, /* column: */ 1); struct tokenizer* tokenizer = new_tokenizer( /* stream: */ stream, /* inital position (mutated): */ position); istream_read(stream); tokenizer_next(tokenizer); if (tokenizer->token->kind == tk_EOF) { // error: empty file TODO; } struct environment* environment = new_environment( /* fallback: */ NULL); environment_declare_builtins( /* this: */ environment); while (tokenizer->token->kind != tk_EOF) { struct statement* statement = parse( /* tokenizer: */ tokenizer); struct stringtree* error_messages = statement_prettyprint_errors(statement); if (error_messages) { // print one (or more) error expressions TODO; // exit(1); TODO; } if (flags->echo) { struct stringtree* stree = statement_prettyprint( /* instance: */ statement, /* color factory: */ cfactory, /* precedence level: */ 0); stringtree_println(stree); free_stringtree(stree); } statement_execute( /* instance: */ statement, /* environment: */ environment, /* color factory: */ cfactory, /* print value: */ true); free_stringtree(error_messages); free_statement(statement); } free_environment(environment); free_tokenizer(tokenizer); free_position(position); free_string(filename); free_istream(stream); #endif break; } case ik_file: { dpvs(flags->input_file); assert(flags->input_file); struct ostream* b_stdout = new_file_ostream( /* file descriptor: */ 1); struct wcostream* wc_stdout = new_ostream_wcostream( /* binary stream: */ b_stdout); struct istream* stream = new_file_istream( /* path: */ flags->input_file); struct wcistream* wcstream = new_istream_wcistream( /* binary stream: */ stream); struct string* filename = new_string_from_ascii( /* data: */ flags->input_file, /* len: */ (size_t) -1); struct position* position = new_position( /* filename: */ filename, /* line number: */ 1, /* column: */ 1); struct tokenizer* tokenizer = new_tokenizer( /* wide-character stream: */ wcstream, /* inital position (mutated): */ position); istream_read(stream); wcistream_read(wcstream); tokenizer_next(tokenizer); while (tokenizer->token->kind == tk_newline) { tokenizer_next(tokenizer); } if (tokenizer->token->kind == tk_EOF) { // error: empty file TODO; } while (tokenizer->token->kind != tk_EOF) { struct statement* statement = parse( /* tokenizer: */ tokenizer); struct stringtree* error_messages = statement_prettyprint_errors(statement); if (error_messages) { // print one (or more) error expressions TODO; // exit(1); TODO; } if (flags->echo) { struct stringtree* stree = statement_prettyprint( /* chosen color reference: */ NULL, /* instance: */ statement, /* color factory: */ cfactory, /* print with color? */ flags->rainbow); stringtree_println(stree, wc_stdout); free_stringtree(stree); } statement_execute( /* instance: */ statement, /* environment: */ &environment, /* booleans: */ booleans, /* color factory: */ cfactory, /* wide-character stdout: */ wc_stdout, /* print value: */ true, /* print with color?: */ flags->rainbow); while (tokenizer->token->kind == tk_newline) { tokenizer_next(tokenizer); } free_stringtree(error_messages); free_statement(statement); } free_tokenizer(tokenizer); free_position(position); free_string(filename); free_wcostream(wc_stdout); free_wcistream(wcstream); free_istream(stream); free_ostream(b_stdout); break; } case ik_interactive: { TODO; // maybe this should go into it's own file, because it's complicated \ beyond parsing and executing the expression. // maintain the line as a character array // whenever there's a mutation, re-parse // if the text is empty: // grey the prompt // the input will never contain a newline, it might contain a semicolon // color the expression \ which will color the tokens \ maybe set all tokens to grey first? // redraw the input line with colored tokens // the parse will come back happy or unhappy: // if happy: // make the prompt green // if unhappy: // make prompt red // for all found 'syntax error' expressions: // print it's message on a new line, offset at the position \ of the incedent. // if the user hits enter: // ... on an empty prompt: // new line, redraw grey prompt. // ... on an unhappy expression: // maybe blink the error messages? // ... on a happy expression: // new line // evaluate // '${id} = ' print result // new line // grey the prompt. // increment line number // save the result into '${id++}' // free result break; } default: { TODO; break; } } free_environment(environment); free_color_factory(cfactory); free_booleans(booleans); free_cmdln_flags(flags); EXIT; return 0; }