Skip to content

Commit b99d262

Browse files
authored
Merge pull request #50 from AvicennaJr/dev
Dev
2 parents 5964deb + 35a083e commit b99d262

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+1861
-292
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Go
22

33
on:
44
push:
5-
branches: [ main ]
5+
branches: [ main, dev ]
66

77
jobs:
88

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,5 @@ testbinaries/
5050
tests_random/
5151
nuru
5252
Notes.md
53-
gotest
5453
tutorials/en/*
55-
upx
54+
config.json

Makefile

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,57 @@
1-
VERSION=0.3.0
1+
VERSION=0.3.0-dev
22

33
build_linux:
44
@echo 'building linux binary...'
5-
env GOOS=linux GOARCH=amd64 go build -o nuru
5+
env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o nuru
6+
@echo 'shrinking binary...'
7+
./upx --brute nuru
68
@echo 'zipping build....'
79
tar -zcvf nuru_linux_amd64_v${VERSION}.tar.gz nuru
810
@echo 'cleaning up...'
911
rm nuru
1012

1113
build_windows:
1214
@echo 'building windows executable...'
13-
env GOOS=windows GOARCH=amd64 go build -o nuru_windows_amd64_v${VERSION}.exe
15+
env GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o nuru_windows_amd64_v${VERSION}.exe
16+
@echo 'zipping build...'
17+
./upx --brute nuru_windows_amd64_v${VERSION}.exe
1418

1519
build_mac:
1620
@echo 'building mac binary...'
17-
env GOOS=darwin GOARCH=amd64 go build -o nuru
21+
env GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o nuru
22+
@echo 'shrinking binary...'
23+
./upx --brute nuru
1824
@echo 'zipping build...'
1925
tar -zcvf nuru_mac_amd64_v${VERSION}.tar.gz nuru
2026
@echo 'cleaning up...'
2127
rm nuru
2228

2329
build_android:
2430
@echo 'building android binary'
25-
env GOOS=android GOARCH=arm64 go build -o nuru
31+
env GOOS=android GOARCH=arm64 go build -ldflags="-s -w" -o nuru
2632
@echo 'zipping build...'
2733
tar -zcvf nuru_linux_amd64_v${VERSION}.tar.gz nuru
2834
@echo 'cleaning up...'
2935
rm nuru
3036

3137
build_test:
32-
go build -o test
33-
mv test testbinaries/
38+
go build -ldflags="-s -w" -o nuru
39+
40+
dependencies:
41+
@echo 'checking dependencies...'
42+
go mod tidy
3443

3544
test:
36-
go test -v ./parser/
37-
go test -v ./ast/
38-
go test -v ./evaluator/
39-
go test -v ./object/
40-
go test -v ./lexer/
45+
@echo -e '\nTesting Lexer...'
46+
@./gotest --format testname ./lexer/
47+
@echo -e '\nTesting Parser...'
48+
@./gotest --format testname ./parser/
49+
@echo -e '\nTesting AST...'
50+
@./gotest --format testname ./ast/
51+
@echo -e '\nTesting Object...'
52+
@./gotest --format testname ./object/
53+
@echo -e '\nTesting Evaluator...'
54+
@./gotest --format testname ./evaluator/
4155

4256
clean:
4357
go clean

ast/ast.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ type MethodExpression struct {
549549
Object Expression
550550
Method Expression
551551
Arguments []Expression
552+
Defaults map[string]Expression
552553
}
553554

554555
func (me *MethodExpression) expressionNode() {}
@@ -577,3 +578,70 @@ func (i *Import) String() string {
577578
}
578579
return out.String()
579580
}
581+
582+
type PackageBlock struct {
583+
Token token.Token
584+
Statements []Statement
585+
}
586+
587+
func (pb *PackageBlock) statementNode() {}
588+
func (pb *PackageBlock) TokenLiteral() string { return pb.Token.Literal }
589+
func (pb *PackageBlock) String() string {
590+
var out bytes.Buffer
591+
592+
for _, s := range pb.Statements {
593+
out.WriteString(s.String())
594+
}
595+
596+
return out.String()
597+
}
598+
599+
type Package struct {
600+
Token token.Token
601+
Name *Identifier
602+
Block *BlockStatement
603+
}
604+
605+
func (p *Package) expressionNode() {}
606+
func (p *Package) TokenLiteral() string { return p.Token.Literal }
607+
func (p *Package) String() string {
608+
var out bytes.Buffer
609+
610+
out.WriteString("pakeji " + p.Name.Value + "\n")
611+
out.WriteString("::\n")
612+
for _, s := range p.Block.Statements {
613+
out.WriteString(s.String())
614+
}
615+
out.WriteString("\n::")
616+
617+
return out.String()
618+
}
619+
620+
type At struct {
621+
Token token.Token
622+
}
623+
624+
func (a *At) expressionNode() {}
625+
func (a *At) TokenLiteral() string { return a.Token.Literal }
626+
func (a *At) String() string { return "@" }
627+
628+
type PropertyAssignment struct {
629+
Token token.Token // the '=' token
630+
Name *PropertyExpression
631+
Value Expression
632+
}
633+
634+
func (pa *PropertyAssignment) expressionNode() {}
635+
func (pa *PropertyAssignment) TokenLiteral() string { return pa.Token.Literal }
636+
func (pa *PropertyAssignment) String() string { return "Ngl I'm tired" }
637+
638+
type PropertyExpression struct {
639+
Expression
640+
Token token.Token // The . token
641+
Object Expression
642+
Property Expression
643+
}
644+
645+
func (pe *PropertyExpression) expressionNode() {}
646+
func (pe *PropertyExpression) TokenLiteral() string { return pe.Token.Literal }
647+
func (pe *PropertyExpression) String() string { return "Ngl I'm tired part two" }

docs/sw/comments.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

evaluator/assign.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ func evalAssign(node *ast.Assign, env *object.Environment) object.Object {
1111
return val
1212
}
1313

14-
env.Set(node.Name.Value, val)
15-
return NULL
14+
obj := env.Set(node.Name.Value, val)
15+
return obj
1616
}

evaluator/at.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package evaluator
2+
3+
import (
4+
"github.com/AvicennaJr/Nuru/ast"
5+
"github.com/AvicennaJr/Nuru/object"
6+
)
7+
8+
func evalAt(node *ast.At, env *object.Environment) object.Object {
9+
if at, ok := env.Get("@"); ok {
10+
return at
11+
}
12+
return newError("Iko nje ya scope")
13+
}

evaluator/builtins.go

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,28 @@ var builtins = map[string]*object.Builtin{
4949
arr = append(arr, arg.Inspect())
5050
}
5151
str := strings.Join(arr, " ")
52-
return &object.String{Value: str}
52+
fmt.Println(str)
5353
}
5454
return nil
5555
},
5656
},
57+
"_andika": {
58+
Fn: func(args ...object.Object) object.Object {
59+
if len(args) == 0 {
60+
return &object.String{Value: "\n"}
61+
} else {
62+
var arr []string
63+
for _, arg := range args {
64+
if arg == nil {
65+
return newError("Hauwezi kufanya operesheni hii")
66+
}
67+
arr = append(arr, arg.Inspect())
68+
}
69+
str := strings.Join(arr, " ")
70+
return &object.String{Value: str}
71+
}
72+
},
73+
},
5774
"aina": {
5875
Fn: func(args ...object.Object) object.Object {
5976
if len(args) != 1 {
@@ -66,38 +83,16 @@ var builtins = map[string]*object.Builtin{
6683
"fungua": {
6784
Fn: func(args ...object.Object) object.Object {
6885

69-
if len(args) > 2 {
70-
return newError("Samahani, Hatuhitaji hoja zaidi ya 2, wewe umeweka %d", len(args))
86+
if len(args) != 1 {
87+
return newError("Samahani, tunahitaji hoja 1, wewe umeweka %d", len(args))
7188
}
7289
filename := args[0].(*object.String).Value
73-
mode := os.O_RDONLY
74-
if len(args) == 2 {
75-
fileMode := args[1].(*object.String).Value
76-
switch fileMode {
77-
case "soma":
78-
mode = os.O_RDONLY
79-
// still buggy, will work on this soon
80-
case "andika":
81-
mode = os.O_WRONLY
82-
os.Remove(filename)
83-
case "ongeza":
84-
mode = os.O_APPEND
85-
default:
86-
return newError("Tumeshindwa kufungua file na mode %s", fileMode)
87-
}
88-
}
89-
file, err := os.OpenFile(filename, os.O_CREATE|mode, 0644)
90+
91+
file, err := os.ReadFile(filename)
9092
if err != nil {
91-
return &object.Null{}
92-
}
93-
var reader *bufio.Reader
94-
var writer *bufio.Writer
95-
if mode == os.O_RDONLY {
96-
reader = bufio.NewReader(file)
97-
} else {
98-
writer = bufio.NewWriter(file)
93+
return &object.Error{Message: "Tumeshinwa kusoma file"}
9994
}
100-
return &object.File{Filename: filename, Reader: reader, Writer: writer, Handle: file}
95+
return &object.File{Filename: filename, Content: string(file)}
10196
},
10297
},
10398

evaluator/call.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ func evalCall(node *ast.CallExpression, env *object.Environment) object.Object {
1717
switch fn := function.(type) {
1818
case *object.Function:
1919
args = evalArgsExpressions(node, fn, env)
20+
case *object.Package:
21+
obj, ok := fn.Scope.Get("andaa")
22+
if !ok {
23+
return newError("Pakeji haina 'andaa'")
24+
}
25+
args = evalArgsExpressions(node, obj.(*object.Function), env)
2026
default:
2127
args = evalExpressions(node.Arguments, env)
2228
}

evaluator/evaluator.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
9090

9191
case *ast.StringLiteral:
9292
return &object.String{Value: node.Value}
93-
93+
case *ast.At:
94+
return evalAt(node, env)
9495
case *ast.ArrayLiteral:
9596
elements := evalExpressions(node.Elements, env)
9697
if len(elements) == 1 && isError(elements[0]) {
@@ -123,7 +124,16 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
123124
// return evalForExpression(node, env)
124125
case *ast.ForIn:
125126
return evalForInExpression(node, env, node.Token.Line)
126-
127+
case *ast.Package:
128+
return evalPackage(node, env)
129+
case *ast.PropertyExpression:
130+
return evalPropertyExpression(node, env)
131+
case *ast.PropertyAssignment:
132+
val := Eval(node.Value, env)
133+
if isError(val) {
134+
return val
135+
}
136+
return evalPropertyAssignment(node.Name, val, env)
127137
case *ast.Assign: // making let temporarily optional as I debug
128138
return evalAssign(node, env)
129139
case *ast.AssignEqual:
@@ -233,7 +243,6 @@ func isTruthy(obj object.Object) bool {
233243
}
234244

235245
func newError(format string, a ...interface{}) *object.Error {
236-
format = fmt.Sprintf("\x1b[%dm%s\x1b[0m", 31, format)
237246
return &object.Error{Message: fmt.Sprintf(format, a...)}
238247
}
239248

@@ -271,6 +280,20 @@ func applyFunction(fn object.Object, args []object.Object, line int) object.Obje
271280
return result
272281
}
273282
return NULL
283+
case *object.Package:
284+
obj := &object.Instance{
285+
Package: fn,
286+
Env: object.NewEnclosedEnvironment(fn.Env),
287+
}
288+
obj.Env.Set("@", obj)
289+
node, ok := fn.Scope.Get("andaa")
290+
if !ok {
291+
return newError("Hamna andaa function")
292+
}
293+
node.(*object.Function).Env.Set("@", obj)
294+
applyFunction(node, args, fn.Name.Token.Line)
295+
node.(*object.Function).Env.Del("@")
296+
return obj
274297
default:
275298
if fn != nil {
276299
return newError("Mstari %d: Hii sio function: %s", line, fn.Type())

0 commit comments

Comments
 (0)