| 1 | /* | 
|---|
| 2 | * Copyright (c) 2011 Jiri Svoboda | 
|---|
| 3 | * All rights reserved. | 
|---|
| 4 | * | 
|---|
| 5 | * Redistribution and use in source and binary forms, with or without | 
|---|
| 6 | * modification, are permitted provided that the following conditions | 
|---|
| 7 | * are met: | 
|---|
| 8 | * | 
|---|
| 9 | * - Redistributions of source code must retain the above copyright | 
|---|
| 10 | *   notice, this list of conditions and the following disclaimer. | 
|---|
| 11 | * - Redistributions in binary form must reproduce the above copyright | 
|---|
| 12 | *   notice, this list of conditions and the following disclaimer in the | 
|---|
| 13 | *   documentation and/or other materials provided with the distribution. | 
|---|
| 14 | * - The name of the author may not be used to endorse or promote products | 
|---|
| 15 | *   derived from this software without specific prior written permission. | 
|---|
| 16 | * | 
|---|
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 
|---|
| 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
|---|
| 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 
|---|
| 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 
|---|
| 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 
|---|
| 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|---|
| 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|---|
| 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|---|
| 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
|---|
| 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|---|
| 27 | */ | 
|---|
| 28 |  | 
|---|
| 29 | /** @file Interactive mode. | 
|---|
| 30 | * | 
|---|
| 31 | * In interactive mode the user types in statements. As soon as the outermost | 
|---|
| 32 | * statement is complete (terminated with ';' or 'end'), the interpreter | 
|---|
| 33 | * executes it. Otherwise it prompts the user until the entire statement | 
|---|
| 34 | * is read in. | 
|---|
| 35 | * | 
|---|
| 36 | * The user interface depends on the OS. In HelenOS we use the CLUI library | 
|---|
| 37 | * which gives us rich line editing capabilities. | 
|---|
| 38 | */ | 
|---|
| 39 |  | 
|---|
| 40 | #include <stdio.h> | 
|---|
| 41 | #include <stdlib.h> | 
|---|
| 42 | #include "os/os.h" | 
|---|
| 43 | #include "ancr.h" | 
|---|
| 44 | #include "assert.h" | 
|---|
| 45 | #include "builtin.h" | 
|---|
| 46 | #include "intmap.h" | 
|---|
| 47 | #include "list.h" | 
|---|
| 48 | #include "mytypes.h" | 
|---|
| 49 | #include "program.h" | 
|---|
| 50 | #include "rdata.h" | 
|---|
| 51 | #include "stree.h" | 
|---|
| 52 | #include "strtab.h" | 
|---|
| 53 | #include "stype.h" | 
|---|
| 54 | #include "input.h" | 
|---|
| 55 | #include "lex.h" | 
|---|
| 56 | #include "parse.h" | 
|---|
| 57 | #include "run.h" | 
|---|
| 58 |  | 
|---|
| 59 | #include "imode.h" | 
|---|
| 60 |  | 
|---|
| 61 | /** Run in interactive mode. | 
|---|
| 62 | * | 
|---|
| 63 | * Repeatedly read in statements from the user and execute them. | 
|---|
| 64 | */ | 
|---|
| 65 | void imode_run(void) | 
|---|
| 66 | { | 
|---|
| 67 | input_t *input; | 
|---|
| 68 | lex_t lex; | 
|---|
| 69 | parse_t parse; | 
|---|
| 70 | stree_program_t *program; | 
|---|
| 71 | stree_stat_t *stat; | 
|---|
| 72 | stree_proc_t *proc; | 
|---|
| 73 | stree_fun_t *fun; | 
|---|
| 74 | stree_symbol_t *fun_sym; | 
|---|
| 75 | stype_t stype; | 
|---|
| 76 | stype_block_vr_t *block_vr; | 
|---|
| 77 | list_node_t *bvr_n; | 
|---|
| 78 | rdata_item_t *rexpr; | 
|---|
| 79 | rdata_item_t *rexpr_vi; | 
|---|
| 80 |  | 
|---|
| 81 | run_t run; | 
|---|
| 82 | run_proc_ar_t *proc_ar; | 
|---|
| 83 |  | 
|---|
| 84 | bool_t quit_im; | 
|---|
| 85 |  | 
|---|
| 86 | /* Create an empty program. */ | 
|---|
| 87 | program = stree_program_new(); | 
|---|
| 88 | program->module = stree_module_new(); | 
|---|
| 89 |  | 
|---|
| 90 | /* Declare builtin symbols. */ | 
|---|
| 91 | builtin_declare(program); | 
|---|
| 92 |  | 
|---|
| 93 | /* Process the library. */ | 
|---|
| 94 | if (program_lib_process(program) != EOK) | 
|---|
| 95 | exit(1); | 
|---|
| 96 |  | 
|---|
| 97 | /* Resolve ancestry. */ | 
|---|
| 98 | ancr_module_process(program, program->module); | 
|---|
| 99 |  | 
|---|
| 100 | /* Bind internal interpreter references to symbols. */ | 
|---|
| 101 | builtin_bind(program->builtin); | 
|---|
| 102 |  | 
|---|
| 103 | /* Resolve ancestry. */ | 
|---|
| 104 | ancr_module_process(program, program->module); | 
|---|
| 105 |  | 
|---|
| 106 | /* Construct typing context. */ | 
|---|
| 107 | stype.program = program; | 
|---|
| 108 | stype.proc_vr = stype_proc_vr_new(); | 
|---|
| 109 | list_init(&stype.proc_vr->block_vr); | 
|---|
| 110 | stype.current_csi = NULL; | 
|---|
| 111 | proc = stree_proc_new(); | 
|---|
| 112 |  | 
|---|
| 113 | fun = stree_fun_new(); | 
|---|
| 114 | fun_sym = stree_symbol_new(sc_fun); | 
|---|
| 115 | fun_sym->u.fun = fun; | 
|---|
| 116 | fun->name = stree_ident_new(); | 
|---|
| 117 | fun->name->sid = strtab_get_sid("$imode"); | 
|---|
| 118 | fun->sig = stree_fun_sig_new(); | 
|---|
| 119 |  | 
|---|
| 120 | stype.proc_vr->proc = proc; | 
|---|
| 121 | fun->symbol = fun_sym; | 
|---|
| 122 | proc->outer_symbol = fun_sym; | 
|---|
| 123 |  | 
|---|
| 124 | /* Create block visit record. */ | 
|---|
| 125 | block_vr = stype_block_vr_new(); | 
|---|
| 126 | intmap_init(&block_vr->vdecls); | 
|---|
| 127 |  | 
|---|
| 128 | /* Add block visit record to the stack. */ | 
|---|
| 129 | list_append(&stype.proc_vr->block_vr, block_vr); | 
|---|
| 130 |  | 
|---|
| 131 | /* Construct run context. */ | 
|---|
| 132 | run_gdata_init(&run); | 
|---|
| 133 |  | 
|---|
| 134 | run.thread_ar = run_thread_ar_new(); | 
|---|
| 135 | list_init(&run.thread_ar->proc_ar); | 
|---|
| 136 | run_proc_ar_create(&run, run.gdata, proc, &proc_ar); | 
|---|
| 137 | list_append(&run.thread_ar->proc_ar, proc_ar); | 
|---|
| 138 |  | 
|---|
| 139 | printf("SBI interactive mode. "); | 
|---|
| 140 | os_input_disp_help(); | 
|---|
| 141 |  | 
|---|
| 142 | quit_im = b_false; | 
|---|
| 143 | while (quit_im != b_true) { | 
|---|
| 144 | parse.error = b_false; | 
|---|
| 145 | stype.error = b_false; | 
|---|
| 146 | run.thread_ar->exc_payload = NULL; | 
|---|
| 147 | run.thread_ar->bo_mode = bm_none; | 
|---|
| 148 |  | 
|---|
| 149 | input_new_interactive(&input); | 
|---|
| 150 |  | 
|---|
| 151 | /* Parse input. */ | 
|---|
| 152 | lex_init(&lex, input); | 
|---|
| 153 | parse_init(&parse, program, &lex); | 
|---|
| 154 |  | 
|---|
| 155 | if (lcur_lc(&parse) == lc_eof) | 
|---|
| 156 | break; | 
|---|
| 157 |  | 
|---|
| 158 | stat = parse_stat(&parse); | 
|---|
| 159 |  | 
|---|
| 160 | if (parse.error != b_false) | 
|---|
| 161 | continue; | 
|---|
| 162 |  | 
|---|
| 163 | /* Type statement. */ | 
|---|
| 164 | stype_stat(&stype, stat, b_true); | 
|---|
| 165 |  | 
|---|
| 166 | if (stype.error != b_false) | 
|---|
| 167 | continue; | 
|---|
| 168 |  | 
|---|
| 169 | /* Run statement. */ | 
|---|
| 170 | run_init(&run); | 
|---|
| 171 | run.program = program; | 
|---|
| 172 | run_stat(&run, stat, &rexpr); | 
|---|
| 173 |  | 
|---|
| 174 | /* Check for unhandled exceptions. */ | 
|---|
| 175 | run_exc_check_unhandled(&run); | 
|---|
| 176 |  | 
|---|
| 177 | if (rexpr != NULL) { | 
|---|
| 178 | /* Convert expression result to value item. */ | 
|---|
| 179 | run_cvt_value_item(&run, rexpr, &rexpr_vi); | 
|---|
| 180 | rdata_item_destroy(rexpr); | 
|---|
| 181 |  | 
|---|
| 182 | /* Check for unhandled exceptions. */ | 
|---|
| 183 | run_exc_check_unhandled(&run); | 
|---|
| 184 | } else { | 
|---|
| 185 | rexpr_vi = NULL; | 
|---|
| 186 | } | 
|---|
| 187 |  | 
|---|
| 188 | /* | 
|---|
| 189 | * rexpr_vi can be NULL if either repxr was null or | 
|---|
| 190 | * if the conversion to value item raised an exception. | 
|---|
| 191 | */ | 
|---|
| 192 | if (rexpr_vi != NULL) { | 
|---|
| 193 | assert(rexpr_vi->ic == ic_value); | 
|---|
| 194 |  | 
|---|
| 195 | /* Print result. */ | 
|---|
| 196 | printf("Result: "); | 
|---|
| 197 | rdata_value_print(rexpr_vi->u.value); | 
|---|
| 198 | printf("\n"); | 
|---|
| 199 |  | 
|---|
| 200 | rdata_item_destroy(rexpr_vi); | 
|---|
| 201 | } | 
|---|
| 202 | } | 
|---|
| 203 |  | 
|---|
| 204 | run_proc_ar_destroy(&run, proc_ar); | 
|---|
| 205 |  | 
|---|
| 206 | /* Remove block visit record from the stack, */ | 
|---|
| 207 | bvr_n = list_last(&stype.proc_vr->block_vr); | 
|---|
| 208 | assert(list_node_data(bvr_n, stype_block_vr_t *) == block_vr); | 
|---|
| 209 | list_remove(&stype.proc_vr->block_vr, bvr_n); | 
|---|
| 210 |  | 
|---|
| 211 | printf("\nBye!\n"); | 
|---|
| 212 | } | 
|---|