예제 #1
0
func cdr(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 1 {
		return nil, scheme.ProcError("cdr requires exactly 1 argument")
	}
	if !scheme.IsCons(args[0]) {
		return nil, scheme.ProcError("cdr requires a cons argument")
	}
	return args[0].(*scheme.Cons).Cdr, nil
}
예제 #2
0
func div(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 2 {
		return nil, scheme.ProcError("/ requires exactly 2 arguments")
	}
	if !scheme.IsNumber(args[0]) || !scheme.IsNumber(args[1]) {
		return nil, scheme.ProcError("/ requires all number arguments")
	}
	left := args[0].(*scheme.Number).Val
	right := args[1].(*scheme.Number).Val
	return scheme.NumberFromInt(left / right), nil
}
예제 #3
0
func setcdr(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 2 {
		return nil, scheme.ProcError("set-cdr! requires exactly 2 arguments")
	}
	pair := args[0]
	value := args[1]
	if !scheme.IsCons(pair) {
		return nil, scheme.ProcError("set-cdr! requires a cons argument")
	}
	pair.(*scheme.Cons).Cdr = value
	return scheme.Nil, nil
}
예제 #4
0
func plus(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) < 2 {
		return nil, scheme.ProcError("+ requires at least 2 arguments")
	}
	var sum int64 = 0
	for _, a := range args {
		if scheme.IsNumber(a) {
			sum += a.(*scheme.Number).Val
		} else {
			return nil, scheme.ProcError("+ requires all number arguments")
		}
	}
	return scheme.NumberFromInt(sum), nil
}
예제 #5
0
func mul(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) < 2 {
		return nil, scheme.ProcError("* requires at least 2 arguments")
	}
	var product int64 = 1
	for _, a := range args {
		if scheme.IsNumber(a) {
			product *= a.(*scheme.Number).Val
		} else {
			return nil, scheme.ProcError("* requires all number arguments")
		}
	}
	return scheme.NumberFromInt(product), nil
}
예제 #6
0
func define(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 2 {
		return nil, scheme.ProcError("define requires exactly 2 arguments")
	}
	idSym, ok := args[0].(*scheme.Symbol)
	if !ok {
		return nil, scheme.ProcError("invalid argument to define")
	}
	val, err := eval.Eval(s, args[1])
	if err != nil {
		return nil, err
	}
	s.DefineHigh(idSym, val)
	return scheme.Nil, nil
}
예제 #7
0
파일: misc.go 프로젝트: rickbutton/goscheme
func display(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 1 {
		return nil, scheme.ProcError("display requires exactly one argument")
	}
	fmt.Printf("%s", args[0])
	return scheme.Nil, nil
}
예제 #8
0
func lambda(s *scheme.Scope, ss []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(ss) < 2 {
		return nil, scheme.ProcError("lambda at least 2 arguments")
	}
	exprs := ss[1:]
	evalScopeParent := scheme.NewScope(s)
	lArgs := ss[0]
	f := func(callScope *scheme.Scope, ss []scheme.Sexpr) (scheme.Sexpr, error) {
		args := lArgs
		evalScope := scheme.NewScope(evalScopeParent)
		aC, ok := args.(*scheme.Cons)
		for args != scheme.Nil {
			if len(ss) == 0 {
				return nil, scheme.ProcError("invalid number of arguments")
			}
			if !ok {
				val := scheme.Unflatten(ss)
				s, k := args.(*scheme.Symbol)
				if !k {
					return nil, scheme.ProcError("Invalid parameter specification")
				}
				evalScope.Define(s, val)
				goto done
			}
			arg := aC.Car
			val := ss[0]
			s, k := arg.(*scheme.Symbol)
			if !k {
				return nil, scheme.ProcError("invalid parameter specification")
			}
			evalScope.Define(s, val)

			ss = ss[1:]
			args = aC.Cdr
			aC, ok = args.(*scheme.Cons)
		}
		if len(ss) > 0 {
			return nil, scheme.ProcError("Invalid number of arguments")
		}
	done:
		for _, e := range exprs[0 : len(exprs)-1] {
			eval.Eval(evalScope, e)
		}
		return eval.Eval(evalScope, exprs[len(exprs)-1])
	}
	return scheme.CreateFunction(f, "lamba"), nil
}
예제 #9
0
func nullCheck(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 1 {
		return nil, scheme.ProcError("null? requires exactly 1 argument")
	}
	_, ok := args[0].(*scheme.NilPrim)
	if ok {
		return scheme.True, nil
	} else {
		return scheme.False, nil
	}
	return nil, nil
}
예제 #10
0
func booleanCheck(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 1 {
		return nil, scheme.ProcError("boolean? requires exactly 1 argument")
	}
	_, ok := args[0].(*scheme.Boolean)
	if ok {
		return scheme.True, nil
	} else {
		return scheme.False, nil
	}
	return nil, nil
}
예제 #11
0
func procCheck(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 1 {
		return nil, scheme.ProcError("proc? requires exactly 1 argument")
	}
	_, okF := args[0].(*scheme.Function)
	_, okP := args[0].(*scheme.Primitive)
	if okF || okP {
		return scheme.True, nil
	} else {
		return scheme.False, nil
	}
	return nil, nil
}
예제 #12
0
func let(s *scheme.Scope, ss []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(ss) < 1 {
		return nil, scheme.ProcError("let requires at least one argument")
	}
	evalScope := scheme.NewScope(s)
	bindings, err := scheme.Flatten(ss[0])
	if err != nil {
		return nil, err
	}
	for _, b := range bindings {
		bs, err := scheme.Flatten(b)
		if err != nil {
			return nil, err
		}
		if len(bs) != 2 {
			return nil, scheme.ProcError("invalid binding on let")
		}
		sym, ok := bs[0].(*scheme.Symbol)
		if !ok {
			return nil, scheme.ProcError("invalid binding on let")
		}
		val, err := eval.Eval(s, bs[1])
		if err != nil {
			return nil, err
		}
		evalScope.Define(sym, val)
	}
	prog := ss[1:]
	var last scheme.Sexpr = scheme.Nil
	for _, l := range prog {
		last, err = eval.Eval(evalScope, l)
		if err != nil {
			return nil, err
		}
	}
	return last, nil
}
예제 #13
0
파일: misc.go 프로젝트: rickbutton/goscheme
func read(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 0 {
		return nil, scheme.ProcError("read must have no arguments")
	}

	br := bufio.NewReader(os.Stdin)
	str, err := br.ReadString('\n')

	r := strings.NewReader(str)
	_, c := lexer.Lex(r)
	expr, err := parser.Parse(c)
	if err != nil {
		return nil, err
	}
	return expr, nil
}
예제 #14
0
func primFor(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 2 {
		return nil, scheme.ProcError("for requires exactly two arguments")
	}
	cond := args[0]
	expr := args[1]
	var val scheme.Sexpr = scheme.Nil
	cv, err := eval.Eval(s, cond)
	if err != nil {
		return nil, err
	}
	for cv != scheme.Nil && cv != scheme.False {
		val, err = eval.Eval(s, expr)
		if err != nil {
			return nil, err
		}
		cv, err = eval.Eval(s, cond)
		if err != nil {
			return nil, err
		}
	}
	return val, nil
}
예제 #15
0
func cons(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 2 {
		return nil, scheme.ProcError("cons requires exactly 2 arguments")
	}
	return &scheme.Cons{args[0], args[1]}, nil
}
예제 #16
0
파일: misc.go 프로젝트: rickbutton/goscheme
func primEval(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 1 {
		return nil, scheme.ProcError("eval requires exactly one argument")
	}
	return eval.Eval(s, args[0])
}
예제 #17
0
func quote(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(args) != 1 {
		return nil, scheme.ProcError("quote requires exactly one argument")
	}
	return args[0], nil
}