Exemplo n.º 1
0
func AddArgs(env *Environment, argNames, args types.Type) (err error) {
	var nameP, valueP, name, value types.Type

	for nameP, valueP = argNames, args; nameP != nil && valueP != nil; {
		name, err = types.Car(nameP)
		if err != nil {
			return
		}

		value, err = types.Car(valueP)
		if err != nil {
			return
		}

		Define(env, name.(*types.Symbol), value)

		nameP, err = types.Cdr(nameP)
		valueP, err = types.Cdr(valueP)
	}

	if nameP != nil || valueP != nil {
		return fmt.Errorf("Wrong number of arguments. Expected %s, got %s", argNames, args)
	}
	return
}
Exemplo n.º 2
0
func eq(env interface{}, args t.Type) (t.Type, error) {
	first, _ := t.Car(args)

	for args, _ := t.Cdr(args); args != nil; args, _ = t.Cdr(args) {
		arg, _ := t.Car(args)

		if !t.Eq(first, arg) {
			return &t.Bool{false}, nil
		}
	}
	return &t.Bool{true}, nil
}
Exemplo n.º 3
0
func equal_Number(env interface{}, args t.Type) (t.Type, error) {
	arg, _ := t.Car(args)
	first, ok := arg.(*t.Number)
	if !ok {
		return nil, fmt.Errorf("=: Not a number: %s", arg)
	}

	for args, _ := t.Cdr(args); args != nil; args, _ = t.Cdr(args) {
		arg, _ := t.Car(args)

		if !t.Eqv(first, arg) {
			return &t.Bool{false}, nil
		}
	}
	return &t.Bool{true}, nil
}
Exemplo n.º 4
0
func if_s(env *environment.Environment, a types.Type) (types.Type, error) {
	test, err := types.Car(a)
	if err != nil {
		return nil, err
	}

	b, err := Eval(env, test)
	if err != nil {
		return nil, err
	}

	var toEval types.Type

	if b.(*types.Bool).Value {
		toEval, err = types.Cadr(a)
		if err != nil {
			return nil, err
		}
	} else {
		temp, err := types.Cdr(a)
		if err != nil {
			return nil, err
		}
		toEval, err = types.Cadr(temp)
		if err != nil {
			return nil, err
		}
	}

	return Eval(env, toEval)
}
Exemplo n.º 5
0
func listToArray(env *environment.Environment, list *types.Pair) (argList []types.Type, err error) {
	for a := list; a != nil; {
		car, err := types.Car(a)
		if err != nil {
			return nil, err
		}

		r, err := Eval(env, car)
		if err != nil {
			return nil, err
		}
		argList = append(argList, r)

		tempA, err := types.Cdr(a)
		if err != nil {
			return nil, err
		}

		var ok bool
		a, ok = tempA.(*types.Pair)
		if !ok && a != nil {
			return nil, fmt.Errorf("Eval: arguments not list: %s", tempA)
		}
	}

	return
}
Exemplo n.º 6
0
func evalArgs(env *environment.Environment, args types.Type) (types.Type, error) {
	if args == nil {
		return nil, nil
	}

	arg, err := types.Car(args)
	if err != nil {
		return nil, err
	}

	car, err := Eval(env, arg)
	if err != nil {
		return nil, err
	}

	next, err := types.Cdr(args)
	if err != nil {
		return nil, err
	}

	cdr, err := evalArgs(env, next)
	if err != nil {
		return nil, err
	}

	return types.Cons(car, cdr), nil
}
Exemplo n.º 7
0
func sub(env interface{}, args t.Type) (t.Type, error) {
	arg, _ := t.Car(args)
	n, ok := arg.(*t.Number)
	if !ok {
		return nil, fmt.Errorf("SUB: Not a number: %s", arg)
	}

	total := n.Value

	for args, _ := t.Cdr(args); args != nil; args, _ = t.Cdr(args) {
		arg, _ := t.Car(args)
		n, ok := arg.(*t.Number)
		if !ok {
			return nil, fmt.Errorf("SUB: Not a number: %s", arg)
		}

		total = total - n.Value
	}
	return &t.Number{total}, nil
}
Exemplo n.º 8
0
func lambda(env *environment.Environment, a types.Type) (types.Type, error) {
	args, err := types.Car(a)
	if err != nil {
		return nil, fmt.Errorf("%s\nLAMBDA: unable to get argument list: %s", err, a)
	}

	text, err := types.Cdr(a)
	if err != nil {
		return nil, fmt.Errorf("%s\nLAMBDA: unable to get function body: %s", err, a)
	}

	return &types.SFunction{text, args, env}, nil
}
Exemplo n.º 9
0
func applySpecialForm(env *environment.Environment, name string, args types.Type) (types.Type, error) {
	switch name {
	case "quote":
		return types.Car(args)
	case "define":
		return nil, define(env, args)
	case "lambda":
		return lambda(env, args)
	case "if":
		return if_s(env, args)
	}
	return nil, nil
}
Exemplo n.º 10
0
func add(env interface{}, args t.Type) (t.Type, error) {
	var total int64 = 0

	for ; args != nil; args, _ = t.Cdr(args) {
		arg, _ := t.Car(args)
		n, ok := arg.(*t.Number)
		if !ok {
			return nil, fmt.Errorf("ADD: Not a number: %s", arg)
		}

		total = total + n.Value
	}
	return &t.Number{total}, nil
}
Exemplo n.º 11
0
func define(env *environment.Environment, args types.Type) error {
	name, err := types.Car(args)
	if err != nil {
		return err
	}
	value, err := types.Cadr(args)
	if err != nil {
		return err
	}

	evaldValue, err := Eval(env, value)
	if err != nil {
		return err
	}

	environment.Define(env, name.(*types.Symbol), evaldValue)
	return nil
}
Exemplo n.º 12
0
func Eval(env *environment.Environment, f types.Type) (types.Type, error) {
	if types.IsPair(f) {
		car, err := types.Car(f)
		if err != nil {
			return nil, err
		}

		cdr, err := types.Cdr(f)
		if err != nil {
			return nil, err
		}

		return Apply(env, car, cdr)
	}

	if types.IsSymbol(f) {
		return environment.Get(env, f.(*types.Symbol))
	}

	return f, nil
}
Exemplo n.º 13
0
func begin(env interface{}, args t.Type) (t.Type, error) {
	var (
		result, expr t.Type
		err          error
	)

	for ; args != nil; args, _ = t.Cdr(args) {
		expr, err = t.Car(args)
		if err != nil {
			return nil, err
		}

		//fmt.Printf("%s\n", expr)

		result, err = Eval(env.(*e.Environment), expr)
		if err != nil {
			return nil, err
		}
	}

	return result, nil
}