Skip to content

Commit

Permalink
Implement stdin redirection, variables
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchpaulus committed Sep 20, 2024
1 parent c0d91c6 commit cb1b273
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 9 deletions.
42 changes: 38 additions & 4 deletions mshell-go/Evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"os/exec"
"strconv"
"strings"
)

type MShellStack []MShellObject
Expand Down Expand Up @@ -351,7 +352,7 @@ func (state EvalState) Evaluate(tokens []Token, stack *MShellStack, context Exec
default:
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot apply '%s' to a %s.\n", t.Line, t.Column, t.Lexeme, obj.TypeName()))
}
} else if t.Type == GREATERTHAN {
} else if t.Type == GREATERTHAN || t.Type == LESSTHAN {
// This can either be normal comparison for numerics, or it's a redirect on a list or quotation.
obj1, err := stack.Pop()
if err != nil {
Expand All @@ -364,16 +365,28 @@ func (state EvalState) Evaluate(tokens []Token, stack *MShellStack, context Exec
}

if obj1.IsNumeric() && obj2.IsNumeric() {
stack.Push(&MShellBool { obj2.FloatNumeric() > obj1.FloatNumeric() })
if t.Type == GREATERTHAN {
stack.Push(&MShellBool { obj2.FloatNumeric() > obj1.FloatNumeric() })
} else {
stack.Push(&MShellBool { obj2.FloatNumeric() < obj1.FloatNumeric() })
}
} else {
switch obj1.(type) {
case *MShellString:
switch obj2.(type) {
case *MShellList:
obj2.(*MShellList).StandardOutputFile = obj1.(*MShellString).Content
if t.Type == GREATERTHAN {
obj2.(*MShellList).StandardOutputFile = obj1.(*MShellString).Content
} else {
obj2.(*MShellList).StandardInputFile = obj1.(*MShellString).Content
}
stack.Push(obj2)
case *MShellQuotation:
obj2.(*MShellQuotation).StandardOutputFile = obj1.(*MShellString).Content
if t.Type == GREATERTHAN {
obj2.(*MShellQuotation).StandardOutputFile = obj1.(*MShellString).Content
} else {
obj2.(*MShellQuotation).StandardInputFile = obj1.(*MShellString).Content
}
stack.Push(obj2)
default:
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot redirect a string to a %s.\n", t.Line, t.Column, obj2.TypeName()))
Expand All @@ -382,6 +395,27 @@ func (state EvalState) Evaluate(tokens []Token, stack *MShellStack, context Exec
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot redirect a %s to a %s.\n", t.Line, t.Column, obj1.TypeName(), obj2.TypeName()))
}
}
} else if t.Type == VARSTORE {
obj, err := stack.Pop()
if err != nil {
return FailWithMessage(fmt.Sprintf("%d:%d: Nothing on stack to store into variable %s.\n", t.Line, t.Column, t.Lexeme[1:]))
}

state.Variables[t.Lexeme[1:]] = obj
} else if t.Type == VARRETRIEVE {
name := t.Lexeme[:len(t.Lexeme) - 1]
obj, ok := state.Variables[name]
if !ok {
var message strings.Builder
message.WriteString(fmt.Sprintf("%d:%d: Variable %s not found.\n", t.Line, t.Column, name))
message.WriteString("Variables:\n")
for key, _ := range state.Variables {
message.WriteString(fmt.Sprintf(" %s\n", key))
}
return FailWithMessage(message.String())
}

stack.Push(obj)
} else {
return FailWithMessage(fmt.Sprintf("%d:%d: We haven't implemented the token type '%s' yet.\n", t.Line, t.Column, t.Type))
}
Expand Down
18 changes: 13 additions & 5 deletions mshell/tests/test_file_go.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,22 @@ if test "$?" -eq 0; then
exit 1
fi
else
diff_output="$(diff "$TMP_ERR" "$1".stderr)"
if test "$?" -eq 0; then
printf "%s passed\n" "$1"
else
if test ! -f "$1".stderr; then
printf "%s FAILED\n" "$1"
printf "==================\n"
printf "%s\n" "$diff_output"
printf "Expected success but got failure.\n"
cat "$TMP_ERR"
exit 1
else
diff_output="$(diff "$TMP_ERR" "$1".stderr)"
if test "$?" -eq 0; then
printf "%s passed\n" "$1"
else
printf "%s FAILED\n" "$1"
printf "==================\n"
printf "%s\n" "$diff_output"
exit 1
fi
fi
fi

Expand Down

0 comments on commit cb1b273

Please sign in to comment.