int read_list(char *start, char **end, Atom *result) { Error err; char *token; Atom p = nil; *result = nil; *end = start; // for(; ;) { err = lex(*end, &token, end); //printf("%s\n", token); //err = lex(start, &token, end); if(err) return ERROR_SYNTAX; if(token[0] == ')') return ERROR_OK; Atom item; if(token[0] == '.' && *end - token == 1) { if(nilp(p)) return ERROR_SYNTAX; err = read_expr(*end, end, &item); if(err) return err; cdr(p) = item; err = lex(*end, &token, end); /* when there is '.', must be the end*/ if(token[0] != ')') return ERROR_SYNTAX; return ERROR_OK; } err = read_expr(token, end, &item); //err = read_expr(*end, end, &item); if(err) return ERROR_SYNTAX; if(nilp(p)) { /* first item */ *result = cons(item, nil); p = *result; } else { cdr(p) = cons(item, nil); p = cdr(p); } } }
void repl() { char *input; while ((input = readline("> ")) != NULL) { int ss = stack_size; read_start:; #ifdef READLINE if (input && *input) add_history(input); #endif const char *p = input; error err; atom expr; err = read_expr(p, &p, &expr); if (err == ERROR_FILE) { /* read more lines */ char *line = readline(" "); if (!line) break; input = strcat_alloc(&input, "\n"); input = strcat_alloc(&input, line); free(line); goto read_start; } if (!err) { while (1) { atom result; error err = macex_eval(expr, &result); if (err) { print_error(err); printf("error in expression:\n"); print_expr(expr); putchar('\n'); break; } else { print_expr(result); puts(""); } err = read_expr(p, &p, &expr); if (err != ERROR_OK) { break; } } } else { print_error(err); } stack_restore(ss); free(input); } }
int main(int argc, char **argv) { // Debug flags debug_gc = getEnvFlag("MINILISP_DEBUG_GC"); always_gc = getEnvFlag("MINILISP_ALWAYS_GC"); // Memory allocation memory = alloc_semispace(); // Constants and primitives Symbols = Nil; void *root = NULL; DEFINE2(env, expr); *env = make_env(root, &Nil, &Nil); define_constants(root, env); define_primitives(root, env); // The main loop printf("%s", ">"); for (;;) { *expr = read_expr(root); if (!*expr) return 0; if (*expr == Cparen) error("Stray close parenthesis"); if (*expr == Dot) error("Stray dot"); print(eval(root, env, expr)); printf("\n%s", ">"); } }
int true_main(int argc, char *argv[]) { if (lisp_prompt) { jl_lisp_prompt(); return 0; } jl_array_t *args = jl_alloc_cell_1d(argc); jl_set_global(jl_current_module, jl_symbol("ARGS"), (jl_value_t*)args); int i; for (i=0; i < argc; i++) { jl_arrayset(args, i, (jl_value_t*)jl_cstr_to_string(argv[i])); } jl_set_const(jl_current_module, jl_symbol("JULIA_HOME"), jl_cstr_to_string(julia_home)); // run program if specified, otherwise enter REPL if (program) { return exec_program(); } init_repl_environment(); jl_function_t *start_client = (jl_function_t*)jl_get_global(jl_base_module, jl_symbol("_start")); if (start_client) { jl_apply(start_client, NULL, 0); return 0; } // client event loop not available; use fallback blocking version int iserr = 0; again: ; JL_TRY { if (iserr) { jl_show(jl_exception_in_transit); ios_printf(ios_stdout, "\n\n"); iserr = 0; } while (1) { char *input = read_expr("julia> "); if (!input || ios_eof(ios_stdin)) { ios_printf(ios_stdout, "\n"); break; } jl_value_t *ast = jl_parse_input_line(input); jl_value_t *value = jl_toplevel_eval(ast); jl_show(value); ios_printf(ios_stdout, "\n\n"); } } JL_CATCH { iserr = 1; goto again; } return 0; }
char *extract_arg_string(const char ** const ptr, arg_context_t *context) { bool fReadResult = read_expr((char **) ptr, context->arg, _T(",")); if (fReadResult == true) { if (**ptr == ',') { context->fExpectingMore = true; (*ptr)++; } else { context->fExpectingMore = false; } } else { if (context->fExpectingMore == true) { SetLastSPASMError(SPASM_ERR_VALUE_EXPECTED); } return NULL; } return context->arg; }
// Reader marcro ' (single quote). It reads an expression and returns (quote <expr>). static Obj *read_quote(void *root) { DEFINE2(sym, tmp); *sym = intern(root, "quote"); *tmp = read_expr(root); *tmp = cons(root, tmp, &Nil); *tmp = cons(root, sym, tmp); return *tmp; }
int true_main(int argc, char *argv[]) { if (lisp_prompt) { jl_lisp_prompt(); return 0; } jl_array_t *args = jl_alloc_cell_1d(argc); jl_set_global(jl_system_module, jl_symbol("ARGS"), (jl_value_t*)args); int i; for (i=0; i < argc; i++) { jl_arrayset(args, i, (jl_value_t*)jl_cstr_to_string(argv[i])); } jl_set_const(jl_system_module, jl_symbol("JULIA_HOME"), jl_cstr_to_string(julia_home)); // run program if specified, otherwise enter REPL if (program) { return exec_program(); } init_repl_environment(); have_color = detect_color(); char *prompt = have_color ? jl_prompt_color : jl_prompt_plain; prompt_length = strlen(jl_prompt_plain); prompt_string = prompt; jl_function_t *start_client = (jl_function_t*) jl_get_global(jl_system_module, jl_symbol("_start")); if (start_client == NULL) { repl_print_prompt(); // client event loop not available; use fallback blocking version int iserr = 0; again: ; JL_TRY { if (iserr) { if (have_color) { ios_printf(ios_stdout, jl_color_normal); } jl_show(jl_exception_in_transit); ios_printf(ios_stdout, "\n\n"); iserr = 0; } while (1) { read_expr(prompt); } } JL_CATCH { iserr = 1; goto again; } }
ListPtr Parser::read_list() { CellPtr head = make_cell(); CellPtr current = head; m_word = m_scanner->get_word(); ExprPtr expr; if (m_word.type == ")") { return head; } else { expr = read_expr(); head->setcar(expr); m_word = m_scanner->get_word(); } while (m_word.type != ")") { if (m_word.type == ".") { m_word = m_scanner->get_word(); expr = read_expr(); current->setcdr(expr); m_word = m_scanner->get_word(); } else if (m_word.type == ")") { break; } else { expr = read_expr(); CellPtr new_cell = make_cell(); new_cell->setcar(expr); current->setcdr(new_cell); current = new_cell; m_word = m_scanner->get_word(); } } return head; }
// Reads a list. Note that '(' has already been read. static Obj *read_list(void *root) { DEFINE3(obj, head, last); *head = Nil; for (;;) { *obj = read_expr(root); if (!*obj) error("Unclosed parenthesis"); if (*obj == Cparen) return reverse(*head); if (*obj == Dot) { *last = read_expr(root); if (read_expr(root) != Cparen) error("Closed parenthesis expected after dot"); Obj *ret = reverse(*head); (*head)->cdr = *last; return ret; } *head = cons(root, obj, head); } }
ExprPtr Parser::read_eval() { ExprPtr last_result; m_word = m_scanner->get_word(); while (m_word.type != "EOF") { ExprPtr expr = read_expr(); last_result = expr->eval_trace(); m_word = m_scanner->get_word(); } return last_result; }
AST_stmt* readASTStmt(BufferedReader *reader) { uint8_t type = reader->readByte(); if (VERBOSITY("parsing") >= 2) printf("type = %d\n", type); if (type == 0) return NULL; uint8_t checkbyte = reader->readByte(); assert(checkbyte == 0xae); switch (type) { case AST_TYPE::Assign: return read_assign(reader); case AST_TYPE::AugAssign: return read_augassign(reader); case AST_TYPE::Break: return read_break(reader); case AST_TYPE::ClassDef: return read_classdef(reader); case AST_TYPE::Continue: return read_continue(reader); case AST_TYPE::Expr: return read_expr(reader); case AST_TYPE::For: return read_for(reader); case AST_TYPE::FunctionDef: return read_functiondef(reader); case AST_TYPE::Global: return read_global(reader); case AST_TYPE::If: return read_if(reader); case AST_TYPE::Import: return read_import(reader); case AST_TYPE::ImportFrom: return read_importfrom(reader); case AST_TYPE::Pass: return read_pass(reader); case AST_TYPE::Print: return read_print(reader); case AST_TYPE::Return: return read_return(reader); case AST_TYPE::While: return read_while(reader); case AST_TYPE::With: return read_with(reader); default: fprintf(stderr, "Unknown stmt node type (parser.cpp:" STRINGIFY(__LINE__) "): %d\n", type); exit(1); break; } }
void repl() { char *input; while ((input = readline("> ")) != NULL) { int ss = stack_size; read_start: arc_reader_unclosed = 0; #ifdef READLINE if (input && *input) add_history(input); #endif char *buf = (char *)malloc(strlen(input) + 4); sprintf(buf, "(%s\n)", input); const char *p = buf; error err; atom result; atom code_expr; err = read_expr(p, &p, &code_expr); if (arc_reader_unclosed > 0) { /* read more lines */ char *line = readline(" "); if (!line) break; input = strcat_alloc(&input, "\n"); input = strcat_alloc(&input, line); goto read_start; } if (!err) { while (!no(code_expr)) { err = macex_eval(car(code_expr), &result); if (err) { print_error(err); break; } else { print_expr(result); putchar('\n'); } code_expr = cdr(code_expr); } } stack_restore(ss); free(buf); free(input); } }
t_bistro *read_input(void) { t_bistro *bistro; if (!(bistro = malloc(sizeof (t_bistro)))) my_puterror(E_THE_WORLD_IS_OVER); if ((bistro->form = my_getchar() == 51)) read_rpn_op(bistro); else read_infix_op(bistro); if (!(bistro->base = malloc(sizeof (t_base)))) my_puterror(E_THE_WORLD_IS_OVER); if ((bistro->base->base_len = my_getchar()) < 2) my_puterror(E_ARITH); read_base(bistro); read_expr(bistro); return bistro; }
int main() { // Debug flags debug_gc = getEnvFlag("MINILISP_DEBUG_GC"); always_gc = getEnvFlag("MINILISP_ALWAYS_GC"); // Memory allocation memory = (void *)memory1; // Init constants Obj trueObj, nilObj, dotObj, cparenObj; True = &trueObj; Nil = &nilObj; Dot = &dotObj; Cparen = &cparenObj; True->type = TTRUE; Nil->type = TNIL; Dot->type = TDOT; Cparen->type = TCPAREN; // Constants and primitives Symbols = Nil; void *root = NULL; DEFINE2(env, expr); *env = make_env(root, &Nil, &Nil); define_constants(root, env); define_primitives(root, env); // The main loop for (;;) { setjmp(&jmpbuf); *expr = read_expr(root); if (!*expr) return 0; if (*expr == Cparen) error("Stray close parenthesis"); if (*expr == Dot) error("Stray dot"); print(eval(root, env, expr)); printf("\n"); } }
action read_action(deserializer & d) { action_kind k = static_cast<action_kind>(d.read_char()); unsigned rbp; switch (k) { case action_kind::Skip: return notation::mk_skip_action(); case action_kind::Binder: d >> rbp; return notation::mk_binder_action(rbp); case action_kind::Binders: d >> rbp; return notation::mk_binders_action(rbp); case action_kind::Expr: d >> rbp; return notation::mk_expr_action(rbp); case action_kind::Exprs: { name sep; expr rec; optional<expr> ini; bool is_fold_right; d >> sep >> rec; if (d.read_bool()) { ini = read_expr(d); } d >> is_fold_right >> rbp; optional<name> terminator; if (d.read_bool()) terminator = read_name(d); return notation::mk_exprs_action(sep, rec, ini, terminator, is_fold_right, rbp); } case action_kind::ScopedExpr: { expr rec; bool use_lambda_abstraction; d >> rec >> rbp >> use_lambda_abstraction; return notation::mk_scoped_expr_action(rec, rbp, use_lambda_abstraction); } case action_kind::LuaExt: return notation::mk_ext_lua_action(d.read_string().c_str()); case action_kind::Ext: break; } lean_unreachable(); }
char *parse_emit_string (const char *ptr, ES_TYPE type, void *echo_target) { static int level = 0; char *word = NULL; int session; bool fWasParsed; char *name_end; level++; arg_context_t context = ARG_CONTEXT_INITIALIZER; while ((word = extract_arg_string(&ptr, &context)) != NULL) { // handle strings if (word[0] == '"') { char *next = next_expr (word, EXPR_DELIMS); if (*next != '\0') goto echo_error; reduce_string (word); if (type == ES_ECHO) { if (echo_target != NULL) { fprintf ((FILE *) echo_target, "%s", word); } } else if (type == ES_FCREATE) { eb_append((expand_buf_t *) echo_target, word, strlen(word)); } else { int i; for (i = 0; word[i]; i++) { if ((mode & MODE_NORMAL) || (mode & MODE_LIST)) write_out (word[i]); stats_datasize++; program_counter++; } } } else { int value; session = StartSPASMErrorSession(); fWasParsed = parse_num(word, &value); if (fWasParsed == true) { switch (type) { case ES_ECHO: { if (echo_target != NULL) { fprintf ((FILE *) echo_target, "%d", value); } break; } #ifdef USE_BUILTIN_FCREATE case ES_FCREATE: { char buffer[256]; sprintf_s(buffer, "%d", value); eb_append((expand_buf_t *) echo_target, buffer, -1); break; } #endif case ES_BYTE: { write_arg(value, ARG_NUM_8, 0, 0); stats_datasize++; program_counter++; break; } case ES_WORD: { write_arg(value, ARG_NUM_16, 0, 0); stats_datasize+=2; program_counter+=2; break; } case ES_LONG: { write_arg(value, ARG_NUM_24, 0, 0); stats_datasize+=3; program_counter+=3; break; } } ReplaySPASMErrorSession(session); } else if (IsSPASMErrorSessionFatal(session) == false && type != ES_FCREATE) { switch (type) { case ES_ECHO: break; case ES_BYTE: { add_pass_two_expr(word, ARG_NUM_8, 0, 0); stats_datasize++; program_counter++; break; } case ES_WORD: { add_pass_two_expr(word, ARG_NUM_16, 0, 0); stats_datasize+=2; program_counter+=2; break; } case ES_LONG: { add_pass_two_expr(word, ARG_NUM_24, 0, 0); stats_datasize += 3; program_counter += 3; break; } } ReplayFatalSPASMErrorSession(session); } else { char name[256]; char *next; define_t *define; name_end = word; //printf("error occured: %d, forward: %d, value: %d\n", error_occurred, parser_forward_ref_err, value); read_expr (&name_end, name, "("); //printf("Looking up %s\n", name); next = name_end; read_expr (&next, NULL, ")"); if (*next != '\0') goto echo_error; if ((define = search_defines (name))) { char *expr; list_t *args = NULL; //handle defines if (define->contents == NULL) { SetLastSPASMError(SPASM_ERR_ARG_USED_WITHOUT_VALUE, name); } if (*(name_end - 1) == '(') name_end--; name_end = parse_args (name_end, define, &args); if (!name_end) return (char *) ptr; expr = parse_define (define); if (expr != NULL) { arg_context_t nested_context = ARG_CONTEXT_INITIALIZER; // Is it some kind of argument list? const char *nested_expr = expr; extract_arg_string(&nested_expr, &nested_context); if (extract_arg_string(&nested_expr, &nested_context) != NULL) { // if it is, plug it in to the emit string parse_emit_string(expr, type, echo_target); } else { if (IsErrorInSPASMErrorSession(session, SPASM_ERR_EXCEEDED_RECURSION_LIMIT) == false) { int inner_session = StartSPASMErrorSession(); parse_emit_string(expr, type, echo_target); if (IsSPASMErrorSessionFatal(inner_session)) { EndSPASMErrorSession(inner_session); AddSPASMErrorSessionAnnotation(session, _T("Error during evaluation of macro '%s'"), define->name); ReplaySPASMErrorSession(session); } else { EndSPASMErrorSession(inner_session); } //ReplaySPASMErrorSession(session); } else { ReplaySPASMErrorSession(session); } } free (expr); } remove_arg_set (args); } else { echo_error: switch (type) { case ES_ECHO: { if (echo_target != NULL) { fprintf((FILE *) echo_target, "(error)"); } break; } case ES_FCREATE: { SetLastSPASMError(SPASM_ERR_LABEL_NOT_FOUND, word); eb_append((expand_buf_t *) echo_target, "(error)", -1); break; } } ReplaySPASMErrorSession(session); } } EndSPASMErrorSession(session); } } if (type == ES_ECHO && level == 1) { if (echo_target == stdout) putchar ('\n'); else { if (echo_target != NULL) { fclose ((FILE *) echo_target); } } } level--; return (char *) ptr; }
char *handle_directive (const char *ptr) { static const char *dirs[] = {"db", "dw", "end", "org", "byte", "word", "fill", "block", "addinstr", "echo", "error", "list", "nolist", "equ", "show", "option", "seek", "assume", "dl", "long", NULL}; char name_buf[32]; int dir; //same deal as handle_preop, just with directives instead bool valid_directive = false; unsigned name_len = 0; while (ptr[name_len] != 0 && !isspace(ptr[name_len])) { name_len++; } // If longer than name_buf, it can't be a valid directive. if (name_len < sizeof(name_buf)) { // Copy string for comparing against memcpy(name_buf, ptr, name_len); name_buf[name_len] = 0; dir = 0; while (dirs[dir]) { if (!strcasecmp(dirs[dir], name_buf)) { valid_directive = true; break; } dir++; } } if (!valid_directive) return handle_opcode_or_macro ((char *) ptr - 1); ptr = skip_whitespace(&ptr[name_len]); switch (dir) { case 0: //DB case 4: //BYTE { ptr = parse_emit_string (ptr, ES_BYTE, NULL); break; } case 1: //DW case 5: //WORD { ptr = parse_emit_string (ptr, ES_WORD, NULL); break; } case 18: //DL case 19: //LONG { ptr = parse_emit_string (ptr, ES_LONG, NULL); break; } case 3: //ORG { int value; char value_str[256] = ""; bool fResult = read_expr(&ptr, value_str, ""); if (fResult == true) { if (parse_num(value_str, &value) == true) { if (value < 0) { SetLastSPASMError(SPASM_ERR_INVALID_ADDRESS, skip_whitespace(value_str)); } else { program_counter = value; } } } if ((fResult == false) || (strlen(skip_whitespace(value_str)) == 0)) { SetLastSPASMError(SPASM_ERR_VALUE_EXPECTED); } break; } case 6: //FILL case 7: //BLOCK { int size, fill_value; char szSize[256], szFill[256]; bool old_listing_on = listing_on; //listing_on = false; read_expr (&ptr, szSize, ","); parse_num (szSize, &size); ptr = skip_whitespace (ptr); if (*ptr == ',') ptr++; if (read_expr (&ptr, szFill, "")) { //if there's a value to fill the block with, then handle that parse_num (szFill, &fill_value); } else { //otherwise use 0 fill_value = 0; } if (size < 0) { SetLastSPASMError(SPASM_ERR_SIZE_MUST_BE_POSITIVE, szSize); listing_on = old_listing_on; break; } if (fill_value < -128 || fill_value > 255) { SetLastSPASMWarning(SPASM_WARN_TRUNCATING_8); } program_counter += size; stats_datasize += size; while (size-- > 0) write_out (fill_value & 0xFF); //listing_on = old_listing_on; break; } case 8: //ADDINSTR { instr *instr = (struct _instr *) malloc (sizeof (struct _instr)); char word[256]; int result; char *mnemonic; size_t i, base = 0, size_left; int j; opcode *last_opcode = NULL, *curr_opcode = all_opcodes, *new_opcode; memset (instr, 0, sizeof (struct _instr)); // Mnemonic if (!read_expr (&ptr, word, " \t")) goto addinstr_fail; mnemonic = strdup (word); // Args if (!read_expr (&ptr, word, " \t")) goto addinstr_fail; reduce_string (word); instr->args = strdup (word); // Instruction data if (!read_expr (&ptr, word, " \t")) goto addinstr_fail; conv_hex (word, word + strlen (word), &result); instr->instr_size = strlen (word) / 2; for (j = instr->instr_size - 1; j >= 0; j--) instr->instr_data[instr->instr_size - j - 1] = (result >> (j * 8)) & 0xFF; // Size if (!read_expr (&ptr, word, " \t")) goto addinstr_fail; if (!parse_num (word, &instr->size)) goto addinstr_fail; // Class read_expr (&ptr, word, " \t"); // Extended read_expr (&ptr, word, " \t"); // End data ... if (read_expr (&ptr, word, " \t")) { int output; conv_hex (word, word + strlen (word), &output); instr->end_data = (unsigned char) output; instr->has_end_data = true; } size_left = instr->size - instr->instr_size; while ((i = strcspn (&instr->args[base], "*")) + base != strlen (instr->args)) { switch (size_left - instr->has_end_data) { case 2: ((char *) instr->args)[base+i] = '*'; break; case 1: ((char *) instr->args)[base+i] = '&'; break; default: ((char *) instr->args)[base+i] = '&'; break; //show_error ("Invalid wildcard type in ADDRINSTR"); //goto addinstr_fail; break; } size_left -= 2; base += i + 1; } new_opcode = (opcode *) malloc (sizeof (opcode)); new_opcode->name = mnemonic; new_opcode->num_instrs = 1; new_opcode->use_count = 0; new_opcode->instrs = instr; new_opcode->is_added = true; while (curr_opcode) { if (strcasecmp (mnemonic, curr_opcode->name) == 0) break; last_opcode = curr_opcode; curr_opcode = curr_opcode->next; } if (curr_opcode == NULL) { last_opcode->next = new_opcode; new_opcode->next = NULL; } else { new_opcode->next = curr_opcode; if (last_opcode) last_opcode->next = new_opcode; else all_opcodes = new_opcode; } // You can ignore class, etc ptr = skip_to_line_end (ptr); break; addinstr_fail: SetLastSPASMError(SPASM_ERR_INVALID_ADDINSTR); if (instr && instr->args) free ((void *) instr->args); if (instr) free (instr); ptr = skip_to_line_end(ptr); break; } case 9: //ECHO { if (ptr[0] == '>') { char target_format[2] = "w"; FILE *echo_target; char filename[MAX_PATH]; char temp_filename[MAX_PATH]; define_t *define; if ((++ptr)[0] == '>') target_format[0] = 'a'; ptr = skip_whitespace (ptr + 1); if (is_end_of_code_line (ptr)) { SetLastSPASMError(SPASM_ERR_FILENAME_EXPECTED); return NULL; } read_expr (&ptr, filename, " \t"); // Is the filename given a macro? if ((define = search_defines (filename))) strncpy (filename, skip_whitespace(define->contents), sizeof (filename)); reduce_string(filename); if (is_abs_path(filename)) { strncpy(temp_filename, skip_whitespace (filename), sizeof (temp_filename)); } else { strncpy(temp_filename, temp_path, sizeof (temp_filename)); strncat(temp_filename, "/", sizeof (temp_filename) - 1); strncat(temp_filename, skip_whitespace (filename), sizeof (temp_filename) - 1); } echo_target = fopen (fix_filename (temp_filename), target_format); if (echo_target == NULL) { SetLastSPASMError(SPASM_ERR_NO_ACCESS, filename); return NULL; } //if the output's redirected to a file, process it now WORD orig_attributes = save_console_attributes(); set_console_attributes (COLOR_GREEN); ptr = parse_emit_string (ptr, ES_ECHO, echo_target); restore_console_attributes(orig_attributes); } else { char expr[256]; read_expr (&ptr, expr, ""); // If it craps out for some reason, save it for the next pass int session = StartSPASMErrorSession(); parse_emit_string (expr, ES_ECHO, NULL); if (IsSPASMErrorSessionFatal(session) == true) { add_pass_two_output (expr, OUTPUT_ECHO); } else if (GetSPASMErrorSessionErrorCount(session) > 0) { WORD orig_attributes = save_console_attributes(); set_console_attributes(COLOR_GREEN); int internal_session = StartSPASMErrorSession(); parse_emit_string (expr, ES_ECHO, stdout); restore_console_attributes(orig_attributes); EndSPASMErrorSession(internal_session); ReplaySPASMErrorSession(session); } else { expand_buf_t *echo = eb_init(256); parse_emit_string (expr, ES_FCREATE, echo); char *echo_string = eb_extract(echo); eb_free(echo); char *expanded_string = escape_string(echo_string); free(echo_string); add_pass_two_output (expanded_string, OUTPUT_ECHO); free(expanded_string); } EndSPASMErrorSession(session); } break; } case 10: //ERROR { expand_buf_t *eb = eb_init(64); ptr = parse_emit_string(ptr, ES_FCREATE, eb); char *error_str = eb_extract(eb); eb_free(eb); SetLastSPASMError(SPASM_ERR_CUSTOM, error_str); free(error_str); break; } case 11: //LIST { //if listing was off already, then the listing // for the start of this line wouldn't have been // written, so make sure the end doesn't get // written either if (!listing_on) listing_for_line_done = true; listing_on = true; break; } case 12: //NOLIST { //if listing is on, then it would've written // the starting stuff for this line already, // so take that out if ((mode & MODE_LIST) && listing_on) listing_offset -= 14; listing_on = false; break; } case 13: //EQU { // Finally, a proper .equ! int value; char value_str[256]; read_expr (&ptr, value_str, ""); if (!parse_num (value_str, &value) && parser_forward_ref_err) { } else { if (last_label == NULL) SetLastSPASMError(SPASM_ERR_EQUATE_MISSING_LABEL); else last_label->value = value; } break; } case 14: //SHOW { char name[256]; define_t *define; //get the name read_expr (&ptr, name, ""); define = search_defines (name); if (define == NULL) { //if it doesn't exist yet, save it for the second pass add_pass_two_output (name, OUTPUT_SHOW); } else { //otherwise, show it now show_define (define); } break; } case 15: //OPTION { char *word = NULL; arg_context_t context = ARG_CONTEXT_INITIALIZER; while ((word = extract_arg_string(&ptr, &context)) != NULL) { char name[256], *expr = word; char *define_name; define_t *define; read_expr(&expr, name, "="); if (*expr == '=') { expr++; } if (!(isalpha(name[0]))) { SetLastSPASMError(SPASM_ERR_INVALID_OPTION, name); return (char *) ptr; } if (is_end_of_code_line (skip_whitespace (expr))) expr = strdup ("1"); else { //if (!parse_num (expr, NULL)) // return NULL; expr = strdup (expr); } if (strlen (name) == 0) { show_error ("Invalid option statement"); return NULL; } define_name = (char *) malloc (strlen (name) + 3); strcat (strcpy (define_name, "__"), name); define = add_define (define_name, NULL); set_define (define, expr, -1, false); free(expr); } break; } case 16: //SEEK { int value; char value_str[256]; read_expr (&ptr, value_str, ""); parse_num (value_str, (int *) &value); //printf("value_str: %s\npc: %d\n", value_str, program_counter); if (value > program_counter && (value - program_counter > output_buf_size - (out_ptr - output_contents))) show_fatal_error ("Seek location %d out of bounds", value); else if (value < program_counter && (value - (int) program_counter + (out_ptr - output_contents) < 0)) show_fatal_error ("Seek value %d too small", value); out_ptr += value - ((int) program_counter); //printf("base: %p; ptr: %p\n", output_contents, out_ptr); program_counter = value; break; } case 17: //ASSUME { char args[256]; read_expr(&ptr, args, ""); char word[256]; char *value_str = args; read_expr(&value_str, word, "="); int value = 1; bool success = true; if (*value_str == '=') { success = parse_num(value_str+1, &value); } if (!(mode & MODE_EZ80) || strcasecmp(word, "adl") || !success) { SetLastSPASMError(SPASM_ERR_INVALID_OPTION, args); return (char *)ptr; } adl_mode = (value != 0); break; } } return (char *) ptr; }
int main (int argc, char **argv) { int curr_arg = 1; bool case_sensitive = false; bool is_storage_initialized = false; use_colors = true; extern WORD user_attributes; user_attributes = save_console_attributes (); atexit (restore_console_attributes_at_exit); //if there aren't enough args, show info if (argc < 2) { puts ("SPASM-ng Z80 Assembler by Spencer Putt and Don Straney"); printf ("Version %s (built on %s @ %s)\n", SPASM_NG_VERSION, __DATE__, __TIME__); #ifdef SPASM_NG_GITREV printf ("Git revision %s\n", SPASM_NG_GITREV); #endif #ifdef _M_X64 puts ("64-bit Version"); #endif #ifdef NO_APPSIGN printf ("\nApp signing is NOT available in this build of SPASM.\n"); #endif puts ("\nspasm [options] <input file> <output file>\n"); puts ("Options:\n-E = Assemble eZ80 code\n-T = Generate code listing\n-C = Code counter mode\n-L = Symbol table mode\n-S = Stats mode\n-O = Don't write to output file"); puts ("-I [directory] = Add include directory\n-A = Labels are cAse-sensitive\n-D<name>[=value] = Create a define 'name' [with 'value']"); puts ("-N = Don't use colors for messages"); puts ("-V <Expression> = Pipe expression directly into assembly"); #if defined(_DEBUG) && defined(WIN32) if (IsDebuggerPresent()) { system("PAUSE"); } #endif return EXIT_NORMAL; } //init stuff mode = MODE_NORMAL; in_macro = 0; //otherwise, get any options curr_input_file = strdup("Commandline"); char *starting_input_file = curr_input_file; while (curr_arg < argc) { if (argv[curr_arg][0] == '-' #ifdef _WINDOWS || argv[curr_arg][0] == '/' #endif ) { switch (argv[curr_arg][1]) { //args for different modes case 'O': mode = mode & (~MODE_NORMAL); break; case 'T': mode |= MODE_LIST; break; case 'C': mode |= MODE_CODE_COUNTER; break; case 'L': mode |= MODE_SYMTABLE; break; case 'S': mode |= MODE_STATS; break; case 'E': mode |= MODE_EZ80; all_opcodes = opcode_list_ez80; break; //handle no-colors flag case 'N': use_colors = false; break; //handle include files too case 'I': { char *dir, *p; //make sure there's another argument after it for the include path if (strlen(argv[curr_arg]) > 2) { dir = strdup (&argv[curr_arg][2]); } else { if (curr_arg >= argc - 1) { printf ("%s used without include path\n", argv[curr_arg]); break; } dir = strdup (argv[++curr_arg]); } for (p = strtok (dir, ";,"); p; p = strtok (NULL, ";,")) { include_dirs = list_append (include_dirs, strdup(p)); } free(dir); break; } //and the case-sensitive flag case 'A': case_sensitive = true; break; //handle adding defines case 'D': { char name[256]; char *ptr; define_t *define; if (!is_storage_initialized) { init_storage(); is_storage_initialized = true; } if (strlen (argv[curr_arg]) > 2) { ptr = &argv[curr_arg][2]; } else { if (curr_arg >= argc - 1) { printf ("%s used without define name", argv[curr_arg]); break; } ptr = argv[++curr_arg]; } read_expr (&ptr, name, "="); define = add_define (strdup (name), NULL); if (*skip_whitespace (++ptr) != '\0') define->contents = strdup (ptr); else set_define (define, "1", 1, false); break; } case 'V': { char *line; //check for something after -V if (strlen(argv[curr_arg]) > 2) { line = &argv[curr_arg][2]; } else { //if not lets fail if (curr_arg >= argc - 1) { printf ("%s used without a line to assemble\n", argv[curr_arg]); return EXIT_FATAL_ERROR; } line = argv[++curr_arg]; } mode |= MODE_COMMANDLINE; curr_input_file = strdup("-v"); input_contents = (char *) malloc (strlen(line) + 1 + 2); output_filename = change_extension (curr_input_file, "bin"); strcpy(input_contents, line); strcat(input_contents, "\n"); break; } default: { #ifndef _TEST #ifdef _WINDOWS printf ("Unrecognized option %s\n", argv[curr_arg]); #ifdef SPASM_NG_ENABLE_COM FreeConsole(); return _AtlModule.WinMain(SW_HIDE); #endif #endif #else printf ("Unrecognized option %s\n", argv[curr_arg]); #endif } } } else { //if it's not a flag, then it must be a filename if (curr_input_file && (curr_input_file != starting_input_file) && !output_filename) output_filename = strdup(argv[curr_arg]); else if ((!curr_input_file) || (curr_input_file == starting_input_file)) curr_input_file = strdup(argv[curr_arg]); } curr_arg++; } // Update case sensitivity settings set_case_sensitive (case_sensitive); //check on filenames if (!(mode & MODE_COMMANDLINE) && curr_input_file == starting_input_file) { puts ("No input file specified"); free(starting_input_file); return EXIT_FATAL_ERROR; } if (curr_input_file != starting_input_file) { free(starting_input_file); } if (!output_filename) { output_filename = change_extension (curr_input_file, "bin"); } if (!is_storage_initialized) { init_storage(); is_storage_initialized = true; } output_contents = (unsigned char *) malloc(output_buf_size); ClearSPASMErrorSessions(); int error = run_assembly(); free(output_filename); output_filename = NULL; if (curr_input_file) { free(curr_input_file); curr_input_file = NULL; } if (include_dirs) { list_free(include_dirs, true, NULL); } free(output_contents); output_contents = NULL; ClearSPASMErrorSessions(); free_storage(); #ifdef _WINDOWS _CrtDumpMemoryLeaks(); if (IsDebuggerPresent()) { system("PAUSE"); } #endif return error; }
int main(int argc, char **argv) { Atom expr; Atom result; Atom env; Error err; char input[MAXLINE]; char *end = input; env_init(&env); //print_expr(env); FILE *fp = NULL; /* no arguments were passed */ if(argc < 2) fp = stdin; else { fp = fopen(argv[1], "r"); if(fp == NULL) { fprintf(stderr, "Cannot open file %s\n", argv[1]); return -1; } const char * file_extension = get_filename_extension(argv[1]); if(strcmp(file_extension, "liuyong") != 0) { fprintf(stderr, "file extension must be .liuyong\n"); return -1; } } printf("> "); while(fgets(input, MAXLINE, fp) != NULL) { err = read_expr(input, &end, &expr); //print_expr(expr); if(!err) err = eval_expr(expr, env, &result); switch(err) { case ERROR_OK: print_expr(result); printf("\n"); break; case ERROR_SYNTAX: printf("Syntax Error\n"); break; case ERROR_UNBOUND: printf("Symbol Not Bound\n"); break; case ERROR_TYPE: printf("Wrong Type\n"); break; case ERROR_ARGS: printf("Wrong Nomber Of Arguments\n"); break; } printf("> "); } }
static void read_builtin_set(environment const & env, io_state const &, deserializer & d) { env->add_builtin_set(read_expr(d)); }
static void read_builtin(environment const & env, io_state const &, deserializer & d) { expr v = read_expr(d); env->add_builtin(v); }
static void read_theorem(environment const & env, io_state const &, deserializer & d) { name n = read_name(d); expr t = read_expr(d); expr v = read_expr(d); env->add_theorem(n, t, v); }
static void read_variable(environment const & env, io_state const &, deserializer & d) { name n = read_name(d); expr t = read_expr(d); env->add_var(n, t); }