Skip to content
Merged

Dev #50

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
ba7970d
delete docs folder
AvicennaJr Apr 6, 2023
48fedca
add docs folder inside repl
AvicennaJr Apr 6, 2023
42cb79b
update dependencies
AvicennaJr Apr 6, 2023
93f4b7f
better tests
AvicennaJr Apr 6, 2023
1b22689
better tests formatting
AvicennaJr Apr 6, 2023
0e77096
add ability to shrink binary size
AvicennaJr Apr 6, 2023
3eb5698
add more compression
AvicennaJr Apr 6, 2023
f25e94d
update makefile
AvicennaJr Apr 8, 2023
34ecf71
update dependencies
AvicennaJr Apr 8, 2023
ed78890
add tutorial flags
AvicennaJr Apr 8, 2023
96ba65e
add sw comments docs
AvicennaJr Apr 8, 2023
ad8ae7e
add Tutor() function
AvicennaJr Apr 8, 2023
b97ecb1
add in built documentation
AvicennaJr Apr 8, 2023
0b07512
add dependent binaries
AvicennaJr Apr 8, 2023
750ae94
remove upx and gotest from list
AvicennaJr Apr 8, 2023
dc2820f
update makefile
AvicennaJr Apr 8, 2023
27220ee
add join (unga) method
AvicennaJr Apr 9, 2023
f296ed0
put unlimited number of characters on text editor
AvicennaJr Apr 9, 2023
9a7d656
add print & return output
AvicennaJr Apr 9, 2023
1a82d88
add new line at end
AvicennaJr Apr 9, 2023
6bcd481
return object after assigning
AvicennaJr Apr 10, 2023
f7985a5
make better formatting
AvicennaJr Apr 10, 2023
c5d9780
Add default args to methods
AvicennaJr Apr 10, 2023
788c2ac
Add ability to parse named args
AvicennaJr Apr 10, 2023
2ea4573
add ability to add specific durations (seconds, minutes etc)
AvicennaJr Apr 10, 2023
70a67cd
Add ability to evalute default methods
AvicennaJr Apr 10, 2023
b163ef7
update time tests
AvicennaJr Apr 10, 2023
117ebfc
update requirements
AvicennaJr Apr 12, 2023
15fc744
Revamped main
AvicennaJr Apr 12, 2023
e4ae96e
Add styles package for consistent styling
AvicennaJr Apr 12, 2023
5c3165c
add _andika just for inbuilt editor
AvicennaJr Apr 12, 2023
e5be7a9
no need for manual colors
AvicennaJr Apr 12, 2023
e6265ef
update tests
AvicennaJr Apr 12, 2023
a48252f
return evaluated object
AvicennaJr Apr 12, 2023
7fce53b
account for edge cases
AvicennaJr Apr 12, 2023
4d68693
add better repl
AvicennaJr Apr 12, 2023
f0d8c53
test dev branch too
AvicennaJr Apr 12, 2023
da314fd
better exit message
AvicennaJr Apr 12, 2023
05f7ebc
add defaults to modules
AvicennaJr Apr 12, 2023
2c90c31
add defaults arguments to all modules
AvicennaJr Apr 12, 2023
142db54
pass in the defaults arguments
AvicennaJr Apr 12, 2023
010b61e
fix defs
AvicennaJr Apr 12, 2023
af1041a
add default checks on json module
AvicennaJr Apr 12, 2023
08c41f8
add ability to encode/decode json
AvicennaJr Apr 13, 2023
06bd515
add ability to handle http requests
AvicennaJr Apr 13, 2023
2245094
add ability to manage files
AvicennaJr Apr 13, 2023
41319bc
fungua will only read files
AvicennaJr Apr 13, 2023
a97037a
add os module with exec and exit methods
AvicennaJr Apr 13, 2023
ee17421
update dependencies
AvicennaJr Apr 13, 2023
9690508
some cleanup
AvicennaJr Apr 13, 2023
690f664
add package tokens
AvicennaJr Apr 14, 2023
adbc0ee
Add package tokens to lexer
AvicennaJr Apr 14, 2023
4db3203
add package related ast
AvicennaJr Apr 14, 2023
be64577
add ability to parse package keyword
AvicennaJr Apr 14, 2023
9bf4988
add package parsing function to list
AvicennaJr Apr 14, 2023
2a4190c
add ability to parse @ key
AvicennaJr Apr 14, 2023
d70ad2a
add ability to parse property expressions
AvicennaJr Apr 14, 2023
2e0dedf
add ability to parse property assignment
AvicennaJr Apr 14, 2023
cb25192
add package object
AvicennaJr Apr 14, 2023
4b32d87
add package instance object
AvicennaJr Apr 14, 2023
b916adc
add @ object
AvicennaJr Apr 14, 2023
a4f0f04
add delete method
AvicennaJr Apr 14, 2023
1736e1a
update object list
AvicennaJr Apr 14, 2023
8656d7c
add ability to evaluate property assignment and expression
AvicennaJr Apr 14, 2023
bcf8455
add ability to evaluate package keyword
AvicennaJr Apr 14, 2023
066f7f3
add ability to evaluate @ keyword
AvicennaJr Apr 14, 2023
1ab344a
add ability to evaluate package method calls
AvicennaJr Apr 14, 2023
a933e47
add ability to evaluate package methods
AvicennaJr Apr 14, 2023
2a5538a
add new items to list
AvicennaJr Apr 14, 2023
29648bf
Add ability to import packages written in Nuru
AvicennaJr Apr 14, 2023
582f3ff
fix typo
AvicennaJr Apr 14, 2023
a8fd397
Add sarufi package example
AvicennaJr Apr 14, 2023
c32c412
update gitignore
AvicennaJr Apr 14, 2023
97740ae
update examples
AvicennaJr Apr 18, 2023
80a695c
check for valid arguments
AvicennaJr Apr 18, 2023
ecad767
add params to get method
AvicennaJr Apr 18, 2023
67d4158
allow time object as a parameter to since method
AvicennaJr Apr 18, 2023
bc2cdc1
add since method
AvicennaJr Apr 18, 2023
526d933
add documentation on files
AvicennaJr Apr 18, 2023
00c36c5
add documentation on time
AvicennaJr Apr 18, 2023
1c9208c
add documentation on json
AvicennaJr Apr 18, 2023
100d59c
add documentation on net
AvicennaJr Apr 18, 2023
8f4a6ce
add documentation on package
AvicennaJr Apr 18, 2023
9b0b58e
update table of contents
AvicennaJr Apr 18, 2023
cfc5f95
use --docs/--nyaraka instead of --tutorial/--mafunzo
AvicennaJr Apr 18, 2023
4727ea4
rename function to Docs from Tutor
AvicennaJr Apr 18, 2023
7ea2d6b
rename tutor.go to docs.go
AvicennaJr Apr 18, 2023
a9efe3b
delete tutor.go file
AvicennaJr Apr 18, 2023
f91a391
use Docs() function
AvicennaJr Apr 18, 2023
35a083e
Use Ctrl+R to run commands on windows
AvicennaJr Apr 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Go

on:
push:
branches: [ main ]
branches: [ main, dev ]

jobs:

Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,5 @@ testbinaries/
tests_random/
nuru
Notes.md
gotest
tutorials/en/*
upx
config.json
38 changes: 26 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,43 +1,57 @@
VERSION=0.3.0
VERSION=0.3.0-dev

build_linux:
@echo 'building linux binary...'
env GOOS=linux GOARCH=amd64 go build -o nuru
env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o nuru
@echo 'shrinking binary...'
./upx --brute nuru
@echo 'zipping build....'
tar -zcvf nuru_linux_amd64_v${VERSION}.tar.gz nuru
@echo 'cleaning up...'
rm nuru

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

build_mac:
@echo 'building mac binary...'
env GOOS=darwin GOARCH=amd64 go build -o nuru
env GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o nuru
@echo 'shrinking binary...'
./upx --brute nuru
@echo 'zipping build...'
tar -zcvf nuru_mac_amd64_v${VERSION}.tar.gz nuru
@echo 'cleaning up...'
rm nuru

build_android:
@echo 'building android binary'
env GOOS=android GOARCH=arm64 go build -o nuru
env GOOS=android GOARCH=arm64 go build -ldflags="-s -w" -o nuru
@echo 'zipping build...'
tar -zcvf nuru_linux_amd64_v${VERSION}.tar.gz nuru
@echo 'cleaning up...'
rm nuru

build_test:
go build -o test
mv test testbinaries/
go build -ldflags="-s -w" -o nuru

dependencies:
@echo 'checking dependencies...'
go mod tidy

test:
go test -v ./parser/
go test -v ./ast/
go test -v ./evaluator/
go test -v ./object/
go test -v ./lexer/
@echo -e '\nTesting Lexer...'
@./gotest --format testname ./lexer/
@echo -e '\nTesting Parser...'
@./gotest --format testname ./parser/
@echo -e '\nTesting AST...'
@./gotest --format testname ./ast/
@echo -e '\nTesting Object...'
@./gotest --format testname ./object/
@echo -e '\nTesting Evaluator...'
@./gotest --format testname ./evaluator/

clean:
go clean
68 changes: 68 additions & 0 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ type MethodExpression struct {
Object Expression
Method Expression
Arguments []Expression
Defaults map[string]Expression
}

func (me *MethodExpression) expressionNode() {}
Expand Down Expand Up @@ -577,3 +578,70 @@ func (i *Import) String() string {
}
return out.String()
}

type PackageBlock struct {
Token token.Token
Statements []Statement
}

func (pb *PackageBlock) statementNode() {}
func (pb *PackageBlock) TokenLiteral() string { return pb.Token.Literal }
func (pb *PackageBlock) String() string {
var out bytes.Buffer

for _, s := range pb.Statements {
out.WriteString(s.String())
}

return out.String()
}

type Package struct {
Token token.Token
Name *Identifier
Block *BlockStatement
}

func (p *Package) expressionNode() {}
func (p *Package) TokenLiteral() string { return p.Token.Literal }
func (p *Package) String() string {
var out bytes.Buffer

out.WriteString("pakeji " + p.Name.Value + "\n")
out.WriteString("::\n")
for _, s := range p.Block.Statements {
out.WriteString(s.String())
}
out.WriteString("\n::")

return out.String()
}

type At struct {
Token token.Token
}

func (a *At) expressionNode() {}
func (a *At) TokenLiteral() string { return a.Token.Literal }
func (a *At) String() string { return "@" }

type PropertyAssignment struct {
Token token.Token // the '=' token
Name *PropertyExpression
Value Expression
}

func (pa *PropertyAssignment) expressionNode() {}
func (pa *PropertyAssignment) TokenLiteral() string { return pa.Token.Literal }
func (pa *PropertyAssignment) String() string { return "Ngl I'm tired" }

type PropertyExpression struct {
Expression
Token token.Token // The . token
Object Expression
Property Expression
}

func (pe *PropertyExpression) expressionNode() {}
func (pe *PropertyExpression) TokenLiteral() string { return pe.Token.Literal }
func (pe *PropertyExpression) String() string { return "Ngl I'm tired part two" }
1 change: 0 additions & 1 deletion docs/sw/comments.md

This file was deleted.

4 changes: 2 additions & 2 deletions evaluator/assign.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ func evalAssign(node *ast.Assign, env *object.Environment) object.Object {
return val
}

env.Set(node.Name.Value, val)
return NULL
obj := env.Set(node.Name.Value, val)
return obj
}
13 changes: 13 additions & 0 deletions evaluator/at.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package evaluator

import (
"github.com/AvicennaJr/Nuru/ast"
"github.com/AvicennaJr/Nuru/object"
)

func evalAt(node *ast.At, env *object.Environment) object.Object {
if at, ok := env.Get("@"); ok {
return at
}
return newError("Iko nje ya scope")
}
53 changes: 24 additions & 29 deletions evaluator/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,28 @@ var builtins = map[string]*object.Builtin{
arr = append(arr, arg.Inspect())
}
str := strings.Join(arr, " ")
return &object.String{Value: str}
fmt.Println(str)
}
return nil
},
},
"_andika": {
Fn: func(args ...object.Object) object.Object {
if len(args) == 0 {
return &object.String{Value: "\n"}
} else {
var arr []string
for _, arg := range args {
if arg == nil {
return newError("Hauwezi kufanya operesheni hii")
}
arr = append(arr, arg.Inspect())
}
str := strings.Join(arr, " ")
return &object.String{Value: str}
}
},
},
"aina": {
Fn: func(args ...object.Object) object.Object {
if len(args) != 1 {
Expand All @@ -66,38 +83,16 @@ var builtins = map[string]*object.Builtin{
"fungua": {
Fn: func(args ...object.Object) object.Object {

if len(args) > 2 {
return newError("Samahani, Hatuhitaji hoja zaidi ya 2, wewe umeweka %d", len(args))
if len(args) != 1 {
return newError("Samahani, tunahitaji hoja 1, wewe umeweka %d", len(args))
}
filename := args[0].(*object.String).Value
mode := os.O_RDONLY
if len(args) == 2 {
fileMode := args[1].(*object.String).Value
switch fileMode {
case "soma":
mode = os.O_RDONLY
// still buggy, will work on this soon
case "andika":
mode = os.O_WRONLY
os.Remove(filename)
case "ongeza":
mode = os.O_APPEND
default:
return newError("Tumeshindwa kufungua file na mode %s", fileMode)
}
}
file, err := os.OpenFile(filename, os.O_CREATE|mode, 0644)

file, err := os.ReadFile(filename)
if err != nil {
return &object.Null{}
}
var reader *bufio.Reader
var writer *bufio.Writer
if mode == os.O_RDONLY {
reader = bufio.NewReader(file)
} else {
writer = bufio.NewWriter(file)
return &object.Error{Message: "Tumeshinwa kusoma file"}
}
return &object.File{Filename: filename, Reader: reader, Writer: writer, Handle: file}
return &object.File{Filename: filename, Content: string(file)}
},
},

Expand Down
6 changes: 6 additions & 0 deletions evaluator/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ func evalCall(node *ast.CallExpression, env *object.Environment) object.Object {
switch fn := function.(type) {
case *object.Function:
args = evalArgsExpressions(node, fn, env)
case *object.Package:
obj, ok := fn.Scope.Get("andaa")
if !ok {
return newError("Pakeji haina 'andaa'")
}
args = evalArgsExpressions(node, obj.(*object.Function), env)
default:
args = evalExpressions(node.Arguments, env)
}
Expand Down
29 changes: 26 additions & 3 deletions evaluator/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ func Eval(node ast.Node, env *object.Environment) object.Object {

case *ast.StringLiteral:
return &object.String{Value: node.Value}

case *ast.At:
return evalAt(node, env)
case *ast.ArrayLiteral:
elements := evalExpressions(node.Elements, env)
if len(elements) == 1 && isError(elements[0]) {
Expand Down Expand Up @@ -123,7 +124,16 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
// return evalForExpression(node, env)
case *ast.ForIn:
return evalForInExpression(node, env, node.Token.Line)

case *ast.Package:
return evalPackage(node, env)
case *ast.PropertyExpression:
return evalPropertyExpression(node, env)
case *ast.PropertyAssignment:
val := Eval(node.Value, env)
if isError(val) {
return val
}
return evalPropertyAssignment(node.Name, val, env)
case *ast.Assign: // making let temporarily optional as I debug
return evalAssign(node, env)
case *ast.AssignEqual:
Expand Down Expand Up @@ -233,7 +243,6 @@ func isTruthy(obj object.Object) bool {
}

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

Expand Down Expand Up @@ -271,6 +280,20 @@ func applyFunction(fn object.Object, args []object.Object, line int) object.Obje
return result
}
return NULL
case *object.Package:
obj := &object.Instance{
Package: fn,
Env: object.NewEnclosedEnvironment(fn.Env),
}
obj.Env.Set("@", obj)
node, ok := fn.Scope.Get("andaa")
if !ok {
return newError("Hamna andaa function")
}
node.(*object.Function).Env.Set("@", obj)
applyFunction(node, args, fn.Name.Token.Line)
node.(*object.Function).Env.Del("@")
return obj
default:
if fn != nil {
return newError("Mstari %d: Hii sio function: %s", line, fn.Type())
Expand Down
6 changes: 3 additions & 3 deletions evaluator/evaluator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ kama (10 > 1) {
continue
}

if errObj.Message != fmt.Sprintf("\x1b[%dm%s\x1b[0m", 31, tt.expectedMessage) {
t.Errorf("wrong error message, expected=%q, got=%q", fmt.Sprintf("\x1b[%dm%s\x1b[0m", 31, tt.expectedMessage), errObj.Message)
if errObj.Message != fmt.Sprintf(tt.expectedMessage) {
t.Errorf("wrong error message, expected=%q, got=%q", fmt.Sprintf(tt.expectedMessage), errObj.Message)
}
}
}
Expand Down Expand Up @@ -1110,7 +1110,7 @@ func TestTimeModule(t *testing.T) {
t.Fatalf("Object is not a time object, got=%T", evaluated)
}

_, err := time.Parse("2006-01-02 15:04:05", muda.TimeValue)
_, err := time.Parse("15:04:05 02-01-2006", muda.TimeValue)
if err != nil {
t.Errorf("Wrong time value: got=%v", err)
}
Expand Down
Loading