aboutsummaryrefslogtreecommitdiff
path: root/itr.go
diff options
context:
space:
mode:
authorAlexander Kiryukhin <a.kiryukhin@mail.ru>2022-06-13 04:31:31 +0300
committerAlexander Kiryukhin <a.kiryukhin@mail.ru>2022-06-13 04:31:31 +0300
commit05626592208f56d88523887e2b80c0514f8ac210 (patch)
treeb0db34890e7366008754e975a8f28e878c5b28bf /itr.go
initial
Diffstat (limited to 'itr.go')
-rw-r--r--itr.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/itr.go b/itr.go
new file mode 100644
index 0000000..68616b7
--- /dev/null
+++ b/itr.go
@@ -0,0 +1,78 @@
+package lexpr
+
+import "context"
+
+func infixToRpn(ctx context.Context, tokens <-chan Token) <-chan Token {
+ out := make(chan Token)
+ stack := TokenStack{}
+ go func() {
+ defer func() {
+ if len(stack) > 0 {
+ for {
+ if stack.Head().typ == lp {
+ out <- Token{
+ typ: tokError,
+ value: "invalid brakets",
+ }
+ break
+ }
+ out <- stack.Pop()
+ if len(stack) == 0 {
+ break
+ }
+ }
+ }
+ close(out)
+ }()
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ case tkn, ok := <-tokens:
+ if !ok {
+ return
+ }
+ switch tkn.typ {
+ case number, word, str, tokError:
+ out <- tkn
+ case funct:
+ stack.Push(tkn)
+ case sep:
+ for stack.Head().typ != lp {
+ if len(stack) == 0 {
+ out <- Token{
+ typ: tokError,
+ value: "no arg separator or opening braket",
+ }
+ return
+ }
+ out <- stack.Pop()
+ }
+ case op:
+ for len(stack) > 0 && (stack.Head().typ != op || (stack.Head().priority >= tkn.priority)) {
+ out <- stack.Pop()
+ }
+ stack.Push(tkn)
+ case lp:
+ stack.Push(tkn)
+ case rp:
+ for stack.Head().typ != lp {
+ if len(stack) == 0 {
+ out <- Token{
+ typ: tokError,
+ value: "no opening braket",
+ }
+ return
+ }
+ out <- stack.Pop()
+ }
+ stack.Pop()
+ if stack.Head().typ == funct {
+ out <- stack.Pop()
+ }
+ }
+ }
+ }
+ }()
+ return out
+}