示例#1
0
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);
		}

	}
}
示例#2
0
文件: arcadia.c 项目: kimtg/arcadia
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);
	}
}
示例#3
0
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", ">");
    }
}
示例#4
0
文件: repl.c 项目: ChappedSky/julia
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;
}
示例#5
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;
}
示例#6
0
// 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;
}
示例#7
0
文件: repl.c 项目: julienr/julia
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;
        }
    }
示例#8
0
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;
}
示例#9
0
// 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);
    }
}
示例#10
0
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;
}
示例#11
0
文件: parser.cpp 项目: UIKit0/pyston
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;
    }
}
示例#12
0
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);
	}
}
示例#13
0
文件: input.c 项目: Albatroce/epita
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;
}
示例#14
0
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");
    }
}
示例#15
0
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();
}
示例#16
0
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;
}
示例#17
0
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;
}
示例#18
0
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;
}
示例#19
0
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("> ");
	}
}
示例#20
0
static void read_builtin_set(environment const & env, io_state const &, deserializer & d) {
    env->add_builtin_set(read_expr(d));
}
示例#21
0
static void read_builtin(environment const & env, io_state const &, deserializer & d) {
    expr v      = read_expr(d);
    env->add_builtin(v);
}
示例#22
0
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);
}
示例#23
0
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);
}