Пример #1
0
int
main(int argc, char **argv) {

    const char  *in_filename;
    FILE        *fp = stdout;
    BOOL        pretty_print_only;
    BOOL        analyse_optimise_print;
    BOOL        optimise;
    BOOL        to_file;


    progname = argv[0];
    pretty_print_only = FALSE;
    analyse_optimise_print = FALSE;
    optimise = FALSE;
    to_file = FALSE;

    /* Process command line */
    if ((argc < 2) || (argc > 3)) {
        usage();
        exit(EXIT_FAILURE);
    }

    if (argc == 2) {
        in_filename = argv[1];
    }

    if (argc == 3 && streq(argv[1], "-p")) {
        pretty_print_only = TRUE;
        in_filename = argv[2];
    }
    if (argc == 3 && streq(argv[1], "-c")) {
        analyse_optimise_print = TRUE;
        in_filename = argv[2];
    }

    if (argc == 3 && streq(argv[1], "-f")) {
        to_file = TRUE;
        in_filename = argv[2];
    }


    yyin = fopen(in_filename, "r");
    if (yyin == NULL) {
        perror(in_filename);
        exit(EXIT_FAILURE);
    }

    if (yyparse() != 0) {
        /* The error message will already have been printed. */
        exit(EXIT_FAILURE);
    }

    if (pretty_print_only) {
        pretty_prog(fp, parsed_program);
        return 0;
    }

    if (analyse_optimise_print) {
        print_bold("Original Program:");
        pretty_prog(fp, parsed_program);
        reduce_ast(parsed_program);
        print_bold("\nOptimised Program:");
        pretty_prog(fp, parsed_program);
        print_bold("\n Errors Detected:");
        analyse(parsed_program);
        return 0;
    }

    //Standard compilation
    reduce_ast(parsed_program);
    if (to_file) {
        int in_filename_len = strlen(in_filename);
        char *outfile = checked_malloc((strlen(in_filename) + 4) * sizeof(char));
        //suffix points to the '.' in filename, assuming it ends in ".wiz"
        const char *suffix = &in_filename[in_filename_len - 4];

        //decide whether there is a ".wiz" suffix to remove or not
        if (in_filename_len > 3 && strcmp(suffix, ".wiz") == 0) {
            //in this case remove the last three characters (w, i and z)
            strncpy(outfile, in_filename, in_filename_len - 3);
            //append null-byte because strncpy does not do this automatically
            outfile[in_filename_len - 3] = '\0';
        }
        else {
            //if suffix is not ".wiz", just append ".oz" to end of name
            strncpy(outfile, in_filename, in_filename_len);
            outfile[in_filename_len] = '.';
            //append nullbute in preparation of appending "oz"
            outfile[in_filename_len + 1] = '\0';
        }

        //finally add the "oz" to end of name
        const char *ending = "oz";
        strcat(outfile, ending);

        printf("%s\n", outfile);
        fp = fopen(outfile, "w");
    }

    compile(fp, parsed_program);
    return 0;
}
Пример #2
0
struct Value execute (struct Tree * ast, struct Tree_map * defined, struct Map * let_map){
    struct Value result;
    // first check for special kinds of execution
    if(ast->type == 'k' && string_matches(&ast->content.data.str, &if_const)){
        return if_block(ast, defined, let_map);
    }
    else if(ast->type == 'k' && string_matches(&let_const, &ast->content.data.str)){
        store_let_binding(ast, defined, let_map);
        result.type = 'u';
    }
    else if(ast->type == 'k' && string_matches(&each_const, &ast->content.data.str)){
        for_each(ast, defined, let_map);
        result.type = 'u';
    }
    else if(ast->type == 'k' && string_matches(&map_const, &ast->content.data.str)){
        return map_array(ast, defined, let_map);
    }
    else if(ast->type == 'k' && string_matches(&reduce_const, &ast->content.data.str)){
        return reduce_array(ast, defined, let_map);
    }
    else if(ast->type == 'k' && string_matches(&set_const, &ast->content.data.str)){
        struct Value index = execute(ast->children[0], defined, let_map);
        struct Value item = execute(ast->children[1], defined, let_map);
        struct Value array = execute(ast->children[2], defined, let_map);
        result = array_set(index, item, array);
        return result;
    }
    else if(ast->type == 'k' && string_matches(&for_const, &ast->content.data.str)){
        for_loop(ast, defined, let_map);
        result.type = 'u'; //return undefined
    }
    else if(ast->type == 'k' && string_matches(&do_const, &ast->content.data.str)){
        for(int i = 0; i < ast->size; i++){
            if(i == ast->size-1){
                result = execute(ast->children[i], defined, let_map);
            } else {
                execute(ast->children[i], defined, let_map);
            }
        }
    }
    else if(ast->type == 'k' && string_matches(&read_const, &ast->content.data.str)){
        return read_file(ast->children[0]->content.data.str);
    }
    else if(ast->type == 'k' && string_matches(&substring_const, &ast->content.data.str)){
        struct Value string = execute(ast->children[2], defined, let_map);
        struct Value start = execute(ast->children[0], defined, let_map);
        struct Value end = execute(ast->children[1], defined, let_map);
        if(string.type != 's'){
            ERROR("Non-string value passed into substring: %c.", string.type);
            result.type = 'u';
            return result;
        } else {
            return substring(start.data.ln, end.data.ln, string);
        }
    }
    else if(ast->type == 'k' && string_matches(&switch_const, &ast->content.data.str)){
        return switch_case(ast, defined, let_map);
    }
    else if(ast->type == 'k' && string_matches(&parallel_const, &ast->content.data.str)){
        parallel_execution(ast, defined, let_map);
        result.type = 'u';
    } else {
        // no special execution types found, check for more basic conditions
        int idx;
        if(!ast->size){
            // ast with no children is either a value or a variable
            if(ast->type == 'k'){
                for(int i = 0; i < let_map->size; i++){
                    if(string_matches(&let_map->members[i]->key->data.str, &ast->content.data.str)){
                        return *let_map->members[i]->val;
                    }
                }
                ERROR("Undefined variable: %s", ast->content.data.str.body);
            } else {
                return ast->content;
            }
        }
        else if(ast->type == 'k' && (idx = is_defined_func(defined, ast->content.data.str)) > -1){
            return execute_defined_func(ast, defined, let_map, idx);
        }
        else if(ast->size == 1){
            struct Value a = execute(ast->children[0], defined, let_map);
            if(ast->type == 'k'){
                if(string_matches(&ast->content.data.str, &print_const)){
                    print(a);
                    printf("\n");
                    result.type = 'u';
                }
                else if(string_matches(&ast->content.data.str, &length_const)){
                    return length(a);
                }
                else if(string_matches(&ast->content.data.str, &return_const)){
                    return execute(ast->children[0], defined, let_map);
                }
            }
        }
        else if(ast->size == 2) {
            struct Value a = execute(ast->children[0], defined, let_map);
            struct Value b = execute(ast->children[1], defined, let_map);
            result = apply_core_function(ast, a, b);
        } else {
            result = reduce_ast(ast, defined, let_map);
        }
    }

    return result;
}