Skip to content

Commit

Permalink
Merge branch 'mbuye' into add-class
Browse files Browse the repository at this point in the history
  • Loading branch information
sevenreup committed Jun 6, 2024
2 parents c358751 + 7196731 commit ab6aa6f
Show file tree
Hide file tree
Showing 16 changed files with 188 additions and 28 deletions.
5 changes: 5 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
"request": "launch",
"mode": "auto",
"program": "${workspaceRoot}/src/main.go",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}",
"args": [
"-f",
"./examples/games/tictactoe.ny"
]
}
]
}
69 changes: 69 additions & 0 deletions examples/games/tictactoe.ny
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
mawu[] board = ["","","","","","","","",""];
mawu currentPlayer = "X";
nambala isRunning = zoona;

ndondomeko printBoard() {
lembanzr("---------");
lembanzr(board[0] + " | " + board[1] + " | " + board[2]);
lembanzr("---------");
lembanzr(board[3] + " | " + board[4] + " | " + board[5]);
lembanzr("---------");
lembanzr(board[6] + " | " + board[7] + " | " + board[8]);
lembanzr("---------");
}

ndondomeko checkWin() {
mawu[] winConditions = [
[0, 1, 2], [3, 4, 5], [6, 7, 8],
[0, 3, 6], [1, 4, 7], [2, 5, 8],
[0, 4, 8], [2, 4, 6]
];

za (x = 0; x < winConditions.length(); x++) {
mawu condition = winConditions[x];
ngati (board[condition[0]] != "" && board[condition[0]] == board[condition[1]] && board[condition[0]] == board[condition[2]]) {
bweza zoona;
}
}
bweza bodza;
}

ndondomeko move(player, position) {
ngati (board[position] != "") {
bweza bodza;
}

board[position] = player;
ngati (player == "X") {
currentPlayer = "O";
} kapena {
currentPlayer = "X";
}
bweza zoona;
}

ndondomeko playGame() {
pamene(isRunning) {
printBoard();
lembanzr("Player " + currentPlayer + " turn: ");
nambala playerMove = kuNambala(console.landira());
mawu moved = move(currentPlayer, playerMove - 1);
ngati(moved == bodza) {
lembanzr("Invalid move");
lembanzr("Try again");
lembanzr("---------");
// TODO: Implement a way to continue loop
} kapena {
mawu hasWon = checkWin();
ngati (hasWon == zoona) {
lembanzr("Player " + player + " has won!");
lembanzr("Game Over");
isRunning = bodza;
} kapena {
console.fufuta();
}
}
}
}

playGame();
3 changes: 2 additions & 1 deletion src/evaluator/assignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package evaluator
import (
"github.com/sevenreup/chewa/src/ast"
"github.com/sevenreup/chewa/src/object"
"github.com/sevenreup/chewa/src/values"
)

func evaluateAssigment(node *ast.AssigmentStatement, env *object.Environment) object.Object {
Expand Down Expand Up @@ -42,7 +43,7 @@ func evaluateIndexAssignment(node *ast.IndexExpression, val object.Object, env *

if idx >= len(elements) {
for i := len(elements); i <= idx; i++ {
elements = append(elements, NULL)
elements = append(elements, values.NULL)
}

left.Elements = elements
Expand Down
9 changes: 6 additions & 3 deletions src/evaluator/boolean.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package evaluator

import "github.com/sevenreup/chewa/src/object"
import (
"github.com/sevenreup/chewa/src/object"
"github.com/sevenreup/chewa/src/values"
)

func nativeBoolToBooleanObject(input bool) *object.Boolean {
if input {
return TRUE
return values.TRUE
}
return FALSE
return values.FALSE
}
13 changes: 4 additions & 9 deletions src/evaluator/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ import (

"github.com/sevenreup/chewa/src/ast"
"github.com/sevenreup/chewa/src/object"
)

var (
NULL = &object.Null{}
TRUE = &object.Boolean{Value: true}
FALSE = &object.Boolean{Value: false}
"github.com/sevenreup/chewa/src/values"
)

func Eval(node ast.Node, env *object.Environment) object.Object {
Expand Down Expand Up @@ -84,11 +79,11 @@ func Eval(node ast.Node, env *object.Environment) object.Object {

func isTruthy(obj object.Object) bool {
switch obj {
case NULL:
case values.NULL:
return false
case TRUE:
case values.TRUE:
return true
case FALSE:
case values.FALSE:
return false
default:
return true
Expand Down
7 changes: 4 additions & 3 deletions src/evaluator/evaluator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/sevenreup/chewa/src/lexer"
"github.com/sevenreup/chewa/src/object"
"github.com/sevenreup/chewa/src/parser"
"github.com/sevenreup/chewa/src/values"
"github.com/shopspring/decimal"
"testing"
)
Expand Down Expand Up @@ -78,7 +79,7 @@ func testLiteralExpression(
}

func testNullObject(t *testing.T, obj object.Object) bool {
if obj != NULL {
if obj != values.NULL {
t.Errorf("object is not NULL. got=%T (%+v)", obj, obj)
return false
}
Expand Down Expand Up @@ -618,8 +619,8 @@ func TestHashLiterals(t *testing.T) {
(&object.String{Value: "two"}).MapKey(): 2,
(&object.String{Value: "three"}).MapKey(): 3,
(&object.Integer{Value: decimal.NewFromInt(4)}).MapKey(): 4,
TRUE.MapKey(): 5,
FALSE.MapKey(): 6,
values.TRUE.MapKey(): 5,
values.FALSE.MapKey(): 6,
}
if len(result.Pairs) != len(expected) {
t.Fatalf("Hash has wrong num of pairs. got=%d", len(result.Pairs))
Expand Down
3 changes: 2 additions & 1 deletion src/evaluator/for_loop.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package evaluator
import (
"github.com/sevenreup/chewa/src/ast"
"github.com/sevenreup/chewa/src/object"
"github.com/sevenreup/chewa/src/values"
)

func evalForLoop(node *ast.ForExpression, env *object.Environment) object.Object {
Expand Down Expand Up @@ -59,5 +60,5 @@ func evalForLoop(node *ast.ForExpression, env *object.Environment) object.Object
loop = false
}

return NULL
return values.NULL
}
3 changes: 2 additions & 1 deletion src/evaluator/if.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package evaluator
import (
"github.com/sevenreup/chewa/src/ast"
"github.com/sevenreup/chewa/src/object"
"github.com/sevenreup/chewa/src/values"
)

func evalIfExpression(ie *ast.IfExpression, env *object.Environment) object.Object {
Expand All @@ -15,6 +16,6 @@ func evalIfExpression(ie *ast.IfExpression, env *object.Environment) object.Obje
} else if ie.Alternative != nil {
return Eval(ie.Alternative, env)
} else {
return NULL
return values.NULL
}
}
5 changes: 3 additions & 2 deletions src/evaluator/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package evaluator
import (
"github.com/sevenreup/chewa/src/ast"
"github.com/sevenreup/chewa/src/object"
"github.com/sevenreup/chewa/src/values"
)

func evalIndexExpression(node *ast.IndexExpression, env *object.Environment) object.Object {
Expand Down Expand Up @@ -31,7 +32,7 @@ func evalArrayIndexExpression(array, index object.Object) object.Object {
maxValue := int64(len(arrayObject.Elements) - 1)

if idx < 0 || idx > maxValue {
return NULL
return values.NULL
}

return arrayObject.Elements[idx]
Expand All @@ -49,7 +50,7 @@ func evaluateMapIndex(node *ast.IndexExpression, left, index object.Object) obje
pair, ok := mapObject.Pairs[key.MapKey()]

if !ok {
return NULL
return values.NULL
}

return pair.Value
Expand Down
19 changes: 11 additions & 8 deletions src/evaluator/prefix.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package evaluator

import "github.com/sevenreup/chewa/src/object"
import (
"github.com/sevenreup/chewa/src/object"
"github.com/sevenreup/chewa/src/values"
)

func evalPrefixExpression(operator string, right object.Object) object.Object {
switch operator {
Expand All @@ -15,14 +18,14 @@ func evalPrefixExpression(operator string, right object.Object) object.Object {

func evalBangOperatorExpression(right object.Object) object.Object {
switch right {
case TRUE:
return FALSE
case FALSE:
return TRUE
case NULL:
return TRUE
case values.TRUE:
return values.FALSE
case values.FALSE:
return values.TRUE
case values.NULL:
return values.TRUE
default:
return FALSE
return values.FALSE
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/evaluator/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ func evalStringInfixExpression(
return &object.String{Value: leftVal + rightVal}
case "==":
return nativeBoolToBooleanObject(leftVal == rightVal)
case "!=":
return nativeBoolToBooleanObject(leftVal != rightVal)
default:
return newError("unknown operator: %s %s %s",
left.Type(), operator, right.Type())
Expand Down
23 changes: 23 additions & 0 deletions src/library/functions/converters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package functions

import (
"github.com/sevenreup/chewa/src/object"
"github.com/sevenreup/chewa/src/token"
"github.com/shopspring/decimal"
)

func ParseStringToNumber(env *object.Environment, tok token.Token, args ...object.Object) object.Object {
if len(args) != 1 {
// TODO: Return error dont panic
panic("parse requires exactly one argument")
}

if args[0].Type() != object.STRING_OBJ {
return nil
}

str := args[0].(*object.String).Value
number, _ := decimal.NewFromString(str)

return &object.Integer{Value: number}
}
1 change: 1 addition & 0 deletions src/library/library.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ func init() {

RegisterFunction("lemba", functions.Print)
RegisterFunction("lembanzr", functions.PrintLine)
RegisterFunction("kuNambala", functions.ParseStringToNumber)
}

func RegisterModule(name string, methods map[string]*object.LibraryFunction) {
Expand Down
39 changes: 39 additions & 0 deletions src/library/modules/console.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package modules

import (
"bufio"
"fmt"
"os"
"os/exec"
"runtime"
"strconv"
"strings"

"github.com/sevenreup/chewa/src/values"
"github.com/sevenreup/chewa/src/object"
"github.com/sevenreup/chewa/src/token"
)
Expand All @@ -13,6 +18,8 @@ var ConsoleMethods = map[string]*object.LibraryFunction{}

func init() {
RegisterMethod(ConsoleMethods, "lemba", consolePrint)
RegisterMethod(ConsoleMethods, "fufuta", consoleClear)
RegisterMethod(ConsoleMethods, "landira", consoleRead)
}

func consolePrint(env *object.Environment, tok token.Token, args ...object.Object) object.Object {
Expand All @@ -27,6 +34,38 @@ func consolePrint(env *object.Environment, tok token.Token, args ...object.Objec
return nil
}

func consoleRead(scope *object.Environment, tok token.Token, args ...object.Object) object.Object {
scanner := bufio.NewScanner(os.Stdin)

if len(args) == 1 {
prompt := args[0].(*object.String).Value

fmt.Print(prompt)
}

val := scanner.Scan()

if !val {
return values.NULL
}

return &object.String{Value: scanner.Text()}
}

func consoleClear(scope *object.Environment, tok token.Token, args ...object.Object) object.Object {
if runtime.GOOS == "windows" {
cmd := exec.Command("cmd", "/c", "cls")
cmd.Stdout = os.Stdout
cmd.Run()
} else {
cmd := exec.Command("clear")
cmd.Stdout = os.Stdout
cmd.Run()
}

return nil
}

func libPrint(values []string) {
if len(values) > 0 {
str := make([]string, 0)
Expand Down
6 changes: 6 additions & 0 deletions src/object/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ func (e *Environment) Get(name string) (Object, bool) {
return obj, ok
}
func (e *Environment) Set(name string, val Object) Object {
// TODO: Make sure we dont accidentally mutate data that is not in the current scope
_, ok := e.store[name]
if !ok && e.outer != nil {
e.outer.Set(name, val)
return val
}
e.store[name] = val
return val
}
Expand Down
9 changes: 9 additions & 0 deletions src/values/value.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package values

import "github.com/sevenreup/chewa/src/object"

var (
NULL = &object.Null{}
TRUE = &object.Boolean{Value: true}
FALSE = &object.Boolean{Value: false}
)

0 comments on commit ab6aa6f

Please sign in to comment.