Skip to content

Commit 69a710e

Browse files
committed
Added keyword functions
1 parent 71e582a commit 69a710e

File tree

6 files changed

+60
-8
lines changed

6 files changed

+60
-8
lines changed

go.sum

Whitespace-only changes.

pkg/interpreter/errorHandler.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package interpreter
33
import (
44
"fmt"
55

6-
"github.com/reilandeubank/golox/pkg/scanner"
6+
"github.com/reilandeubank/golisp/pkg/scanner"
77
)
88

99
var hadErrorFlag bool = false

pkg/interpreter/helpers.go

+21-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"reflect"
66

77
"github.com/reilandeubank/golisp/pkg/scanner"
8-
"github.com/reilandeubank/golsip/pkg/parser"
8+
"github.com/reilandeubank/golisp/pkg/parser"
99
)
1010

1111
func isTruthy(object interface{}) bool {
@@ -29,11 +29,11 @@ func isEqual(a interface{}, b interface{}) bool {
2929
return a == b
3030
}
3131

32-
func checkNumberOperand(operator scanner.Token, operand interface{}) error {
32+
func checkNumberOperand(operator scanner.Token, operand interface{}) (bool, error) {
3333
if reflect.TypeOf(operand) == reflect.TypeOf(0.0) || reflect.TypeOf(operand) == reflect.TypeOf(0) {
34-
return nil
34+
return true, nil
3535
}
36-
return &RuntimeError{Token: operator, Message: "Operator must be a number"}
36+
return false, &RuntimeError{Token: operator, Message: "Operator must be a number"}
3737
}
3838

3939
func checkNumberOperands(operator scanner.Token, left interface{}, right interface{}) error {
@@ -59,9 +59,25 @@ func stringify(object interface{}) string {
5959

6060
func isOperator(expr parser.Expression) bool {
6161
switch expr.(type) {
62-
case Operator:
62+
case parser.Operator:
6363
return true
6464
default:
6565
return false
6666
}
6767
}
68+
69+
func (i *Interpreter) cdr(k parser.Keyword) (interface{}, error) {
70+
var elems []parser.Expression
71+
for _, elem := range k.Args {
72+
newExpr, err := i.evaluate(elem)
73+
if err != nil {
74+
return nil, err
75+
}
76+
if expr, ok := newExpr.(parser.Expression); ok {
77+
elems = append(elems, expr)
78+
} else {
79+
return nil, &RuntimeError{Message: "type assertion failed, expected parser.Expression"}
80+
}
81+
}
82+
return parser.ListExpr{Head: elems[1], Tail: elems[2:]}, nil
83+
}

pkg/interpreter/interpreter.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package interpreter
22

33
import (
4-
"fmt"
5-
"github.com/reilandeubank/golisp/parser"
4+
// "fmt"
5+
"github.com/reilandeubank/golisp/pkg/parser"
66
)
77

88
type Interpreter struct {

pkg/interpreter/visitExpr.go

+35
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,45 @@ func (i *Interpreter) VisitListExpr(l parser.ListExpr) (interface{}, error) {
1313
o.Operands = l.Tail
1414
return i.evaluate(o)
1515
}
16+
17+
if k, ok := l.Head.(*parser.Keyword); ok {
18+
k.Args = l.Tail
19+
return i.evaluate(k)
20+
}
1621
return nil, fmt.Errorf("not implemented")
1722
}
1823

1924
func (i *Interpreter) VisitKeywordExpr(k parser.Keyword) (interface{}, error) {
25+
switch k.Keyword.Type {
26+
case scanner.CAR:
27+
car, err := i.evaluate(k.Args[0])
28+
if err != nil {
29+
return nil, err
30+
}
31+
return parser.Atom{Value: car}, nil
32+
case scanner.CDR:
33+
return i.cdr(k)
34+
case scanner.COND:
35+
for j := 0; j < len(k.Args); j += 2 {
36+
condition, err := i.evaluate(k.Args[j])
37+
if err != nil {
38+
return nil, err
39+
}
40+
if isTruthy(condition) && j+1 < len(k.Args) {
41+
return i.evaluate(k.Args[j+1])
42+
}
43+
}
44+
return nil, &RuntimeError{Token: k.Keyword, Message: "Lack of true condition"}
45+
case scanner.NUMBERQ:
46+
if len(k.Args) != 1 {
47+
return nil, &RuntimeError{Token: k.Keyword, Message: "NUMBER? operation must have 1 operand"}
48+
}
49+
expr, err := i.evaluate(k.Args[0])
50+
if err != nil {
51+
return nil, err
52+
}
53+
return checkNumberOperand(k.Keyword, expr)
54+
}
2055
return nil, fmt.Errorf("not implemented")
2156
}
2257

pkg/parser/expr.go

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ func (l ListExpr) String() string {
6767

6868
type Keyword struct {
6969
Keyword scanner.Token
70+
Args []Expression
7071
}
7172

7273
func (k Keyword) Accept(v ExprVisitor) (interface{}, error) {

0 commit comments

Comments
 (0)