/*
 * Add primitive operator name to environment
 * This maps the symbol `sym' to a list
 * (PRIM-OP sym), which is recognized as the
 * evaluator as a special form which causes
 * it to run the routine "do_prim_op()",
 * which is defined lower down in this file.
 */
void add_primop(env_t *e, char *sym)
{
	list_t *l = new_list();
	l->type = LIST;
	add_child(l, mksym("PRIM-OP"));
	add_child(l, mksym(sym));
	env_add(e, sym, l);
}
Exemple #2
0
int main()
{
    Value *result;

    init();
    // List manipulation.
    defnative(mksym("CONS"), native_cons);
    defnative(mksym("CAR"), native_car);
    defnative(mksym("CDR"), native_cdr);

    // Arithmetic.
    defnative(mksym("PLUS"), native_plus);
    defnative(mksym("MINUS"), native_minus);
    defnative(mksym("MUL"), native_mul);
    defnative(mksym("DIV"), native_div);

    // Miscellaneous.
    defnative(mksym("EVAL"), native_eval);
    defglobal(mksym("NIL"), LISP_NIL);

    while (!feof(stdin)) {
        setjmp(toplevel_escape);
        printf("> ");
        result = eval(lread(), global_env);
        printf("\n");
        lwrite(result);
        printf("\n");
    }

    return 0;
}
Exemple #3
0
Value *lreadsym()
{
    char buf[32];
    char *p = buf;
    char ch;
    while (isalpha((ch = getchar()))) {
        *p++ = ch;
    }
    ungetc(ch, stdin);
    *p = '\0';
    return mksym(buf);
}
Exemple #4
0
void init()
{
    int i;
    size_t s = 16384;

    heap = malloc(s);
    heap_end = heap + s;

    for (i = 0; i < SYMBOL_TABLE_SIZE; i++) {
        syms[i] = LISP_NIL;
    }

    quote_sym = mksym("QUOTE");
    lambda_sym = mksym("LAMBDA");
    define_sym = mksym("DEFINE");
    if_sym = mksym("IF");

    // Set up the global environment as a single, "empty" binding.
    // This is done so that we can "splice" global definitions into
    // the global environment rather than "extending" the global
    // environment in the regular fashion. Otherwise, global mutual
    // recursion would not be possible.
    global_env = mkpair(mkpair(LISP_NIL, LISP_NIL), LISP_NIL);
}
Exemple #5
0
int main(int argc, char * argv[]){
	std::cout<<nil->value<<std::endl;
	std::cout<<t->value<<std::endl;
//	std::cout<<mkflt(1.2356).value<<std::endl;
//	loliObj* c = cons(t, nil);
//	loliObj* b = cons(t, c);
//	std::cout<<tail(tail(b))->value<<std::endl;
	std::cout<<"CREATING TEST:"<<std::endl;
	loliObj* test = cons(mksym("a"), cons(mkint(3), cons(mkint(0), nil)));
//	std::cout<<"TEST HEAD: "<<head(test).value<<std::endl;
//	std::cout<<"SUM (1 2 3): "<<proc_sum(test)->value<<std::endl;
	std::cout<<"SUB (\"a\" 3 0): "<<proc_sub(test)->value<<std::endl;
///	std::cout<<"MUL (1 2 3): "<<proc_mul(test)->value<<std::endl;
	std::cout<<"DIV (\"a\" 3 0): "<<proc_div(test)->value<<std::endl;
	std::cout<<"MOD (\"a\" 3 0): "<<proc_mod(test)->value<<std::endl;
	std::cout<<"Length of (\"a\" 3 0) is: "<<prim_length(test)<<std::endl;
	loliObj* testSUM = mkproc(proc_sum);
	//cleanUp();
	//delete test;
	exit(0);
}
Exemple #6
0
Fichier : pipe.c Projet : aiju/hdl
Nodes *
findpipe(ASTNode *n)
{
	Nodes *pipebl, *decls;
	Nodes *r;
	Symbol *go;

	if(n == nil || n->t != ASTPIPEL) return nl(n);
	curpipec = n;
	go = n->n2 != nil ? n->n2->sym : nil;
	stlist.next = stlist.prev = &stlist;
	findstages(n, 0);
	propsets();
	mksym(n->st->up);
	stcur = nil;
	procvars(go, &pipebl, &decls);
	killed = bsnew(stlist.prev->nvars);
	r = decls;
	if(n->n2 != nil) r = nlcat(nl(n->n2), r);
	r = nlcat(r, process(n));
	r = nlcat(r, nl(node(ASTBLOCK, pipebl)));
	return r;
}
Exemple #7
0
Matrix
make_symmetric(Matrix a)
{
    mksym(a);
    return a;
}
Exemple #8
0
 *
 *       Filename:  loli_symbols.cpp
 *
 *    Description:  The Internal Symbols of LoLi
 *
 *        Version:  1.0
 *        Created:  04/05/2014 01:23:47 AM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Z.Shang (), [email protected]
 *   Organization:  
 *
 * =====================================================================================
 */

#include "loli_types.h"

loliObj *nil = mksym("nil");
loliObj *t = mksym("t");
loliObj *lambda = mksym(".\\");
loliObj *set = mksym("set!");
loliObj *quote = mksym("quote");

bool nilp(loliObj* o){
	if(o->type == SYM && o->value == "nil"){
		return true;
	}
	return false;
}
list_t* do_prim_op(char *name, list_t *args)
{
	int i = 0;
	int j;
	int val = 0;
	list_t *l1;
	list_t* nl = c_malloc(sizeof(list_t));
	char *buf;

	if (!strcmp(name, "+")) {
		val = 0;
		for (i = 0; i < args->cc; ++i) {
			if (args->c[i]->type != NUMBER) {
				error_msg("+ expects numbers");
				code_error();
			}
			val += args->c[i]->val;
		}
		nl->type = NUMBER;
		nl->val = val;
		return nl;
	}

	if (!strcmp(name, "-")) {
		if (args->cc == 1) {
			/* single argument: unary minus sign */
			if (args->c[0]->type != NUMBER) {
				error_msg("- expects numbers");
				code_error();
			}
			val = -args->c[0]->val;
		} else {
			/* otherwise, standard N-ary subtraction */
			for (i = 0; i < args->cc; ++i) {
				if (args->c[i]->type != NUMBER) {
					error_msg("- expects numbers");
					code_error();
				}
				if (i == 0)
					val = args->c[i]->val;
				else
					val -= args->c[i]->val;
			}
		}
		nl->val = val;
		nl->type = NUMBER;
		return nl;
	}

	if (!strcmp(name, "*")) {
		val = 1;
		for (i = 0; i < args->cc; ++i) {
			if (args->c[i]->type != NUMBER) {
				error_msg("* expects numbers");
				code_error();
			}
			val *= args->c[i]->val;
		}
		nl->type = NUMBER;
		nl->val = val;
		return nl;
	}

	if (!strcmp(name, "remainder")) {
		if (args->cc != 2
		|| args->c[0]->type != NUMBER
		|| args->c[1]->type != NUMBER) {
			error_msg("`remainder' expects two numbers");
			code_error();
		}
		nl->type = NUMBER;
		nl->val = args->c[0]->val % args->c[1]->val;
		return nl;
	}

	if (!strcmp(name, "=")) {
		if (args->cc != 2
		|| args->c[0]->type != NUMBER
		|| args->c[1]->type != NUMBER) {
			error_msg("= expects two numbers");
			code_error();
		}
		return makebool(args->c[0]->val == args->c[1]->val);
	}

	if (!strcmp(name, ">")) {
		if (args->cc != 2
		|| args->c[0]->type != NUMBER
		|| args->c[1]->type != NUMBER) {
			error_msg("> expects two numbers");
			code_error();
		}
		return makebool(args->c[0]->val > args->c[1]->val);
	}

	if (!strcmp(name, "<")) {
		if (args->cc != 2
		|| args->c[0]->type != NUMBER
		|| args->c[1]->type != NUMBER) {
			error_msg("< expects two numbers");
			code_error();
		}
		return makebool(args->c[0]->val < args->c[1]->val);
	}

	if (!strcmp(name, "<=")) {
		if (args->cc != 2
		|| args->c[0]->type != NUMBER
		|| args->c[1]->type != NUMBER) {
			error_msg("<= expects two numbers");
			code_error();
		}
		return makebool(args->c[0]->val <= args->c[1]->val);
	}

	if (!strcmp(name, ">=")) {
		if (args->cc != 2
		|| args->c[0]->type != NUMBER
		|| args->c[1]->type != NUMBER) {
			error_msg(">= expects two numbers");
			code_error();
		}
		return makebool(args->c[0]->val >= args->c[1]->val);
	}

	if (!strcmp(name, "not")) {
		val = 0;
		if (args->cc != 1) {
				error_msg("`not' expects one argument");
				code_error();
		}
		/* r6rs.pdf section 11.8, page 47 */
		val = args->c[0]->type == BOOL && !args->c[i]->val;
		return makebool(val);
	}


	if (!strcmp(name, "cons")) {
		if (args->cc != 2) {
			error_msg("`cons' expects 2 arguments");
			code_error();
		}
		/* just return the list as-is for now */
		memcpy(nl, args, sizeof(list_t));
		nl->type = CONS;
		return nl;
	}

	if (!strcmp(name, "car")) {
		if (args->cc != 1) {
			error_msg("`car' expects 1 argument");
			code_error();
		}
		if (args->c[0]->type != CONS) {
			error_msg("`car' expects a linked-list");
			code_error();
		}
		if (args->c[0]->cc < 1) {
			error_msg("`car' has failed");
			code_error();
		}
		return args->c[0]->c[0];
	}

	if (!strcmp(name, "cdr")) {
		if (args->cc != 1) {
			error_msg("`cdr' expects 1 argument");
			code_error();
		}
		if (args->c[0]->type != CONS) {
			error_msg("`cdr' expects a linked-list");
			code_error();
		}
		if (args->c[0]->cc < 2) {
			error_msg("`cdr' has failed");
			code_error();
		}
		return args->c[0]->c[1];
	}

	if (!strcmp(name, "null?")) {
		return makebool(args->cc == 1 
			&& (
				((args->c[0]->type == SYMBOL && !strcmp(args->c[0]->head, "NIL"))
				|| (args->c[0]->type == CONS && args->c[0]->cc == 0))));
	}

	if (!strcmp(name, "display")) {
		buf = malloc(LINEBUFSIZ);
		if (!buf) {
			error_msg("malloc failed");
			code_error();
		}
		*buf = 0;
		printout(args->c[0], buf);
#ifdef JS_GUI
		c_writeback(buf);
#else
		printf("%s", buf);
#endif
		free(buf);
		return args->c[0];
	}

	if (!strcmp(name, "pair?")) {
		/* check for null first */
		j = args->cc == 1 
		&& (
			((args->c[0]->type == SYMBOL && !strcmp(args->c[0]->head, "NIL"))
			|| (args->c[0]->type == CONS && args->c[0]->cc == 0)));
		return makebool(!j  /* not null, then the rest */
			&& args->cc == 1 && args->c[0]->type == CONS);
	}

	/* the following bit deals with (eq? A B) --
	 * apparently, eq? checks if two things evaluate
	 * to the same memory pointer. but further hackery
	 * is sufficient to deal with the case (eq? 'foo 'foo) */
	if (!strcmp(name, "eq?")) {
		if (args->cc != 2) {
			error_msg("`eq?' expects two arguments");
			code_error();
		}
		return makebool(args->c[0] == args->c[1]
			|| (args->c[0]->type == SYMBOL 
				&& args->c[1]->type == SYMBOL
				&& !strcmp(args->c[0]->head, args->c[1]->head))
			/* (eq? 'NIL '()) => #t */
			|| (args->c[0]->type == SYMBOL && !strcmp(args->c[0]->head, "NIL")
			    && args->c[1]->type == CONS && args->c[1]->cc == 0)
			/* (eq? '() 'NIL) => #t */
			|| (args->c[1]->type == SYMBOL && !strcmp(args->c[1]->head, "NIL")
			    && args->c[0]->type == CONS && args->c[0]->cc == 0)
			/* (eq? '() '()) => #t */
			|| (args->c[0]->type == CONS && args->c[0]->cc == 0
			    && args->c[1]->type == CONS && args->c[1]->cc == 0));
	}

	if (!strcmp(name, "symbol?")) {
		return makebool(args->cc == 1 
			&& args->c[0]->type == SYMBOL);
	}

	if (!strcmp(name, "number?")) {
		return makebool(args->cc == 1 
			&& args->c[0]->type == NUMBER);
	}

	if (!strcmp(name, "newline")) {
#ifdef JS_GUI
		c_writeback_nl("");
#else
		puts("");
#endif
		return mksym("NIL");
	}

	if (!strcmp(name, "save-to")) {
		if (save_mode) {
			return mksym("NIL");
		}
		save_file = fopen(args->c[0]->head, "w");
		if (!save_file) {
			error_msg("failed to open file for writing");
			code_error();
		}
		save_mode = 1;
		return mksym("savefile-ok");
	}

	if (!strcmp(name, "load")) {
		buf = malloc(strlen(args->c[0]->head) + 1);
		if (!buf) {
			error_msg("malloc failed");
			code_error();
		}
		strcpy(buf, args->c[0]->head);
		load_code_from_file(buf);
		free(buf);
		return mksym("HERP-DERP");
	}

	if (!strcmp(name, "cons2list")) {
		return cons2list(args->c[0]);
	}

	if (!strcmp(name, "debuglog")) {
		stacktracer_barf();
		return mksym("herp-derp");
	}

	if (!strcmp(name, "reverse")) {
		/* r6rs.pdf, page 48 */
		if (args->c[0]->type == CONS)
			l1 = cons2list(args->c[0]);
		else if (args->c[0]->type == LIST)
			l1 = args->c[0];
		else return mksym("NIL");

		if (l1->cc == 0)
			return mksym("NIL");

		nl = new_list();
		nl->type = LIST;
		for (i = l1->cc - 1; i >= 0; --i)
			add_child(nl, l1->c[i]);
		return makelist(nl);
	}

	return NULL;
}
Exemple #10
0
void loli_init_tl(){
	top_env = addToEnv(top_env, cons(mksym("a"), mkflt(10.0011011)));
	top_env = addToEnv(top_env, cons(t, t));
	top_env = addToEnv(top_env, cons(nil, nil));
	top_env = addToEnv(top_env, cons(quote, quote));
	top_env = addToEnv(top_env, cons(mksym("top_env"), top_env));

	//Creating Primitive Operators
	loliObj* loli_sum = mkproc(proc_sum);
	loliObj* loli_mul = mkproc(proc_mul);
	loliObj* loli_sub = mkproc(proc_sub);
	loliObj* loli_div = mkproc(proc_div);
	loliObj* loli_add1 = mkproc(proc_add1);
	loliObj* loli_sub1 = mkproc(proc_sub1);
	loliObj* loli_mod = mkproc(proc_mod);
	loliObj* loli_greater = mkproc(proc_greater);
	loliObj* loli_lesser = mkproc(proc_lesser);
	
	top_env = addToEnv(top_env, cons(mksym("+"), loli_sum));
	top_env = addToEnv(top_env, cons(mksym("*"), loli_mul));
	top_env = addToEnv(top_env, cons(mksym("-"), loli_sub));
	top_env = addToEnv(top_env, cons(mksym("/"), loli_div));
	top_env = addToEnv(top_env, cons(mksym("add1"), loli_add1));
	top_env = addToEnv(top_env, cons(mksym("sub1"), loli_sub1));
	top_env = addToEnv(top_env, cons(mksym("mod"), loli_mod));
	top_env = addToEnv(top_env, cons(mksym(">"), loli_greater));
	top_env = addToEnv(top_env, cons(mksym("<"), loli_lesser));

	loliObj* test = cons(mkint(1), cons(mkflt(2.5), cons(mkint(5), nil)));

	std::cout<<toString(apply(loli_sum, test))<<"\t"<<toString(apply(loli_mul, test))<<"\n"<<toString(apply(loli_sub, test))<<"\t"<<toString(apply(loli_div, test))<<std::endl;

	std::cout<<toString(top_env)<<std::endl;

}