#include <stdio.h>
#include <stdlib.h>
+#include <stddef.h>
#include "opts.h"
#include "grammar.h"
+#include "parser.h"
#include "lexer.h"
/* Command Line Options
*****************************************************************************/
OptionConfig_T Options_Config[] = {
- { SHORT, (char*)"L", (char*)"scan", 0, (char*)"Output the results of lexical analysis and quit"},
- { SHORT, (char*)"P", (char*)"parse", 0, (char*)"Output the results of parsing quit"},
- { END, (char*)NULL, (char*)NULL, 0, (char*)NULL }
+ { "tokens", false, "mode", "Emit the token output of lexical analysis for the given file"},
+ { "ast", false, "mode", "Emit the abstract syntax tree for the given file"},
+ { "repl", false, "mode", "Execute the application in a REPL"},
+ { "staticlib", false, "mode", "Compile the application as a static library"},
+ { "sharedlib", false, "mode", "Compile the application as a shared library"},
+ { "program", false, "mode", "Compile the application as an executable"},
+ { "R", true, "include", "Add a path to the list of require paths"},
+ { NULL, false, NULL, NULL }
};
-/* SCLPL Parser
+/* Tree Printing
*****************************************************************************/
-
void print_indent(int depth) {
for(int i = 0; i < (2 * depth); i++)
printf("%c", ' ');
print_indent(depth);
if (p_tree->tag == ATOM) {
lex_tok_t* p_tok = p_tree->ptr.tok;
- printf("<token(%s)>\n", lexer_tok_type_str(p_tok));
+ printf("<tok %s>\n", lexer_tok_type_str(p_tok));
} else {
- puts("(tree:");
+ puts("(tree");
vec_t* p_vec = p_tree->ptr.vec;
for(size_t idx = 0; idx < vec_size(p_vec); idx++) {
print_tree((tree_t*)vec_at(p_vec, idx), depth+1);
}
}
-/* TODO:
+/* Tree Rewriting
+ *****************************************************************************/
+bool is_punctuation(lex_tok_t* p_tok) {
+ bool ret = false;
+ switch(p_tok->type) {
+ case T_END:
+ case T_LBRACE:
+ case T_RBRACE:
+ case T_LBRACK:
+ case T_RBRACK:
+ case T_LPAR:
+ case T_RPAR:
+ case T_COMMA:
+ ret = true;
+ }
+ return ret;
+}
- * Formalize grammar for parser
- * Paren for function application must be on same line as variable in REPL
- * skip line on error and terminate after full program parse
- * skip line and print on error but do not terminate the REPL
+tree_t* convert_to_ast(tree_t* p_tree) {
+ tree_t* p_newtree = NULL;
+ if (p_tree->tag == ATOM) {
+ if (!is_punctuation(p_tree->ptr.tok))
+ p_newtree = mem_retain(p_tree);
+ } else {
+ vec_t* p_vec = p_tree->ptr.vec;
+ vec_t* p_newvec = vec_new(0);
+ p_newtree = parser_tree_new(TREE, p_newvec);
+ for(size_t idx = 0; idx < vec_size(p_vec); idx++) {
+ tree_t* p_item = convert_to_ast(vec_at(p_vec,idx));
+ if (NULL != p_item)
+ vec_push_back(p_newvec, p_item);
+ }
+ }
+ return p_newtree;
+}
-*/
-int main(int argc, char **argv) {
- Result_T* results = OPTS_ParseOptions( Options_Config, argc, argv );
+/* Driver Modes
+ *****************************************************************************/
+static int emit_tokens(void) {
+ lexer_t* p_lexer = lexer_new(NULL, stdin);
+ lex_tok_t* token;
+ while(NULL != (token = lexer_read(p_lexer))) {
+ printf("<tok %s>\n", lexer_tok_type_str(token));
+ mem_release(token);
+ }
+ mem_release(p_lexer);
+ return 0;
+}
+static int emit_tree(void) {
+ int ret = 0;
+ parser_t* p_parser = parser_new(NULL, stdin);
+ while(!parser_eof(p_parser)) {
+ tree_t* p_tree = grammar_toplevel(p_parser);
+ if (NULL != p_tree) {
+ tree_t* p_ast = convert_to_ast(p_tree);
+ print_tree(p_ast, 0);
+ mem_release(p_tree);
+ mem_release(p_ast);
+ } else {
+ parser_resume(p_parser);
+ ret = 1;
+ }
+ }
+ mem_release(p_parser);
+ return ret;
+}
+
+static int exec_repl(void) {
parser_t* p_parser = parser_new(":> ", stdin);
while(!parser_eof(p_parser)) {
tree_t* p_tree = grammar_toplevel(p_parser);
if (NULL != p_tree) {
- print_tree(p_tree, 0);
+ tree_t* p_ast = convert_to_ast(p_tree);
+ print_tree(p_ast, 0);
mem_release(p_tree);
+ mem_release(p_ast);
puts("OK.");
} else {
parser_resume(p_parser);
}
}
mem_release(p_parser);
+ return 0;
+}
- (void)results;
+static int emit_staticlib(void) {
return 0;
}
+
+static int emit_sharedlib(void) {
+ return 0;
+}
+
+static int emit_program(void) {
+ return 0;
+}
+
+/* TODO:
+
+ * Formalize grammar for parser
+ * Paren for function application must be on same line as variable in REPL
+ * skip line on error and terminate after full program parse
+ * skip line and print on error but do not terminate the REPL
+
+*/
+int main(int argc, char **argv) {
+ opts_parse( Options_Config, argc, argv );
+
+ if (!opts_is_set(NULL,"mode") || opts_equal(NULL, "mode", "repl")) {
+ return exec_repl();
+ } else if (opts_equal(NULL, "mode", "tokens")) {
+ return emit_tokens();
+ } else if (opts_equal(NULL, "mode", "ast")) {
+ return emit_tree();
+ } else if (opts_equal(NULL, "mode", "staticlib")) {
+ return emit_staticlib();
+ } else if (opts_equal(NULL, "mode", "sharedlib")) {
+ return emit_sharedlib();
+ } else if (opts_equal(NULL, "mode", "program")) {
+ return emit_program();
+ }
+
+ opts_reset();
+ return 1;
+}