예제 #1
0
파일: pair.go 프로젝트: rread/rsi
func listLen(d Data) int {
	if nullp(d) {
		return 0
	}
	var i int
	for {
		i++
		d = cdr(d)
		if nullp(d) {
			break
		}
		if !pairp(d) {
			log.Fatal("expecting a list")
		}
	}
	return i
}
예제 #2
0
파일: main.go 프로젝트: rread/rsi
func main() {
	debug := flag.Bool("debug", false, "Enable debugging")
	flag.Parse()
	flag.Args()
	if *debug {
		log.SetLevel(log.Debug)
	}
	env := DefaultEnv()

	if flag.NArg() > 0 {
		for _, f := range flag.Args() {
			buf, err := ioutil.ReadFile(f)
			if err != nil {
				log.Fatal(err)
			}
			repl(string(buf), env)
		}
	}
	replCLI(env)
}
예제 #3
0
파일: eval.go 프로젝트: rread/rsi
func read(l Tokenizer) (Data, error) {
	t := l.NextItem()
	if t == nil {
		return nil, ErrorEOF
	}
	//log.Debugf("scan: %v\n", t)
	switch t.Token {
	case lexer.LEFT_PAREN:
		return readList(l)
	case lexer.RIGHT_PAREN:
		return nil, nil
	case lexer.SYMBOL:
		return internSymbol(t.Lit), nil
	case lexer.QUOTE:
		return readQuote(l)
	case lexer.NUMBER:
		v, err := strconv.ParseFloat(t.Lit, 64)
		if err != nil {
			log.Fatal("Number fail:", err)
		}
		return Number(v), nil
	case lexer.EOF:
		return nil, ErrorEOF
	case lexer.STRING:
		return StringWithValue(t.Lit), nil
	case lexer.TRUE:
		return T, nil
	case lexer.FALSE:
		return False, nil
	case lexer.DOT:
		return _dot, nil
	case lexer.ILLEGAL:
		return nil, errors.New(t.Lit)
	case lexer.COMMENT:
		return read(l)
	}
	return nil, errors.New("Malformed input")
}
예제 #4
0
파일: eval.go 프로젝트: rread/rsi
func eval(expr Data, env *Env) (Data, error) {
	log.Printf("eval: %T: %v\n", expr, expr)
	switch e := expr.(type) {
	case Boolean:
		return e, nil
	case Symbol:
		return env.FindVar(e)
	case Number:
		return e, nil
	case String:
		return e, nil
	case Null:
		return e, nil
	case *Pair:
		c, _ := getSymbol(car(e))
		/* non-Symbols fall through to default */
		switch c {
		case _quote:
			return cadr(e), nil
		case _define:
			return evalDefine(e, env)
		case _set:
			return evalSet(e, env)
		case _if:
			return evalIf(e, env)
		case _let:
			return evalLet(e, env)
		case _begin:
			return evalSequential(cdr(e), env)
		case _quit:
			os.Exit(0)
		case _lambda:
			params, err := getList(cadr(e))
			if err != nil {
				return nil, fmt.Errorf("bad params: %v", err)
			}
			body, err := getList(cddr(e))
			if err != nil {
				return nil, fmt.Errorf("bad body: %v", err)
			}
			return evalLambda(params, body, env)
		case _vars:
			for k, v := range env.vars {
				log.Printf("%v: %v\n", k, v)
			}
			return nil, nil
		default:
			log.Printf("procedure call %v", e)
			proc, err := eval(car(e), env)
			if err != nil {
				return nil, err
			}
			args, err := evalArgs(cdr(e), env)
			if err != nil {
				return nil, err
			}
			switch f := proc.(type) {
			case InternalFunc:
				return f(args)
			case *Lambda:
				var err error
				env, err = ExtendEnv(f.params, args, f.envt)
				if err != nil {
					return nil, err
				}
				return evalSequential(f.body, env)
			default:
				return nil, fmt.Errorf("apply to a non function: %#v %v", proc, args)
			}

		}
	case nil:
		log.Fatal("parsed a nil?")
		return nil, nil
	}
	return nil, fmt.Errorf("Unparsable expression: %v", expr)
}