Skip to content

Commit

Permalink
Add first translation of Evaluator
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchpaulus committed Sep 19, 2024
1 parent c944aa2 commit 2546b2b
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 5 deletions.
119 changes: 119 additions & 0 deletions mshell-go/Evaluator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package main

import (
"io"
"fmt"
"os"
)

type MShellStack []MShellObject

func (objList MShellStack) Peek() (MShellObject, error) {
if len(objList) == 0 {
return nil, fmt.Errorf("Empty stack")
}
return objList[len(objList) - 1], nil
}

func (objList MShellStack) Pop() (MShellObject, error) {
if len(objList) == 0 {
return nil, fmt.Errorf("Empty stack")
}
popped := objList[len(objList) - 1]
objList = objList[:len(objList) - 1]
return popped, nil
}

func (objList MShellStack) Push(obj MShellObject) {
objList = append(objList, obj)
}

type EvalState struct {
PositionalArgs[] string
LoopDepth int32

// private Dictionary<string, MShellObject> _variables = new();
Variables map[string]MShellObject
}

type EvalResult struct {
Success bool
BreakNum int32
}

type ExecuteContext struct {
StandardInput io.Reader
StandardOutput io.Writer
}

func SimpleSuccess() EvalResult {
return EvalResult { true, -1 }
}

func FailWithMessage(message string) EvalResult {
// Log message to stderr
fmt.Fprintf(os.Stderr, message)
return EvalResult { false, -1 }
}

func (state EvalState) Evaluate(tokens []Token, stack MShellStack, context ExecuteContext) EvalResult {
index := 0

// Need a stack of integers
// quotationStack := []int32{}
leftSquareBracketStack := []int{}

for index < len(tokens) {
t := tokens[index]
index++

if t.Type == EOF {
return SimpleSuccess()
} else if t.Type == LITERAL {
stack.Push(&MShellLiteral { t.Lexeme })
} else if t.Type == LEFT_SQUARE_BRACKET {
leftSquareBracketStack = append(leftSquareBracketStack, index)

for {
currentToken := tokens[index]
index++

if index >= len(tokens) || tokens[index].Type == EOF {
return FailWithMessage(fmt.Sprintf("%d:%d: Found unbalanced bracket.\n", currentToken.Line, currentToken.Column))
}

if tokens[index].Type == LEFT_SQUARE_BRACKET {
leftSquareBracketStack = append(leftSquareBracketStack, index)
} else if tokens[index].Type == RIGHT_SQUARE_BRACKET {
if len(leftSquareBracketStack) > 0 {
leftIndex := leftSquareBracketStack[len(leftSquareBracketStack)-1]

if len(leftSquareBracketStack) == 0 {
listStack := []MShellObject{}
tokensWithinList := tokens[leftIndex + 1:index - leftIndex - 1]
result := state.Evaluate(tokensWithinList, listStack, context)
if !result.Success {
return result
}

if result.BreakNum > 0 {
return FailWithMessage("Encountered break within list.\n")
}

l := &MShellList { listStack, nil, nil }
stack.Push(l)
break
}

} else {
return FailWithMessage(fmt.Sprintf("%d:%d: Found unbalanced square bracket.\n", currentToken.Line, currentToken.Column))
}
}
}
} else {
return FailWithMessage(fmt.Sprintf("%d:%d: We haven't implemented the token type '%s' yet.\n", t.Line, t.Column, t.Type))
}
}

return EvalResult { true, -1 }
}
6 changes: 3 additions & 3 deletions mshell-go/Lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ type Token struct {
Column int
Start int
Lexeme string
TokenType TokenType
Type TokenType
}

type Lexer struct {
Expand Down Expand Up @@ -156,7 +156,7 @@ func (l *Lexer) makeToken(tokenType TokenType) Token {
Column: l.col,
Start: l.start,
Lexeme: lexeme,
TokenType: tokenType,
Type: tokenType,
}
}

Expand Down Expand Up @@ -333,7 +333,7 @@ func (l *Lexer) Tokenize() []Token {
for {
t := l.scanToken()
tokens = append(tokens, t)
if t.TokenType == ERROR || t.TokenType == EOF {
if t.Type == ERROR || t.Type == EOF {
break
}
}
Expand Down
1 change: 0 additions & 1 deletion mshell-go/MShellObject.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,4 +236,3 @@ func (obj *MShellPipe) DebugString() string {
// Join each item with a ' | '
return strings.Join(DebugStrs(obj.List.Items), " | ")
}

2 changes: 1 addition & 1 deletion mshell-go/Main.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func main() {
fmt.Println("Tokens:")
for _, t := range tokens {
// Console.Write($"{t.Line}:{t.Column}:{t.TokenType} {t.RawText}\n");
fmt.Printf("%d:%d:%s %s\n", t.Line, t.Column, t.TokenType, t.Lexeme)
fmt.Printf("%d:%d:%s %s\n", t.Line, t.Column, t.Type, t.Lexeme)
}
return
}
Expand Down

0 comments on commit 2546b2b

Please sign in to comment.