Created
September 23, 2023 21:30
-
-
Save yan-aint-nickname/18c37fed73cc8fb3f7e1746ceec6c4e8 to your computer and use it in GitHub Desktop.
Polish notation in go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"errors" | |
"fmt" | |
"slices" | |
"unicode" | |
"unicode/utf8" | |
) | |
const ( | |
ADD = iota | |
SUB | |
DIV | |
MUL | |
INT | |
) | |
var tokens = []string{ | |
ADD: "+", | |
SUB: "-", | |
DIV: "/", | |
MUL: "*", | |
INT: "INT", | |
} | |
type Token struct { | |
t int | |
value int | |
} | |
func (t Token) String() string { | |
return fmt.Sprintf("{typ:%s val:%d}", tokens[t.t], t.value) | |
} | |
func Lex(notation string) ([]Token, error) { | |
tokens := make([]Token, 0) | |
for _, v := range notation { | |
if ok := utf8.ValidRune(v); !ok { | |
return nil, errors.New("Not a valid symbol") | |
} | |
switch { | |
case '+' == v: | |
tokens = append(tokens, Token{t: ADD}) | |
case '-' == v: | |
tokens = append(tokens, Token{t: SUB}) | |
case '*' == v: | |
tokens = append(tokens, Token{t: MUL}) | |
case '/' == v: | |
tokens = append(tokens, Token{t: DIV}) | |
case unicode.IsDigit(v): | |
tokens = append(tokens, Token{t: INT, value: int(v - '0')}) | |
default: | |
return nil, errors.New("Not a valid symbol") | |
} | |
} | |
return tokens, nil | |
} | |
// Dummy queue | |
type Queue struct { | |
head int | |
tail int | |
} | |
func (q *Queue) Push(val int) { | |
q.tail = q.head | |
q.head = val | |
} | |
func Execute(tokens []Token) int { | |
slices.Reverse(tokens) | |
var queue = Queue{head: 0, tail: 0} | |
for _, token := range tokens { | |
switch { | |
case token.t == INT: | |
queue.Push(token.value) | |
case token.t == ADD: | |
queue.Push(queue.tail + queue.head) | |
case token.t == SUB: | |
queue.Push(queue.tail - queue.head) | |
case token.t == MUL: | |
queue.Push(queue.tail * queue.head) | |
case token.t == DIV: | |
queue.Push(queue.tail / queue.head) | |
} | |
} | |
return queue.head | |
} | |
func main() { | |
var userInput string | |
fmt.Scan(&userInput) | |
tokens, err := Lex(userInput) | |
if err != nil { | |
panic(err) | |
} | |
res := Execute(tokens) | |
fmt.Println(res) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment