1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
package expression
import (
"fmt"
"go/token"
)
func (e *Evaluator) ToPRN(in <-chan Token) chan Token {
out := make(chan Token)
stack := &Stack{}
go func() {
defer func() {
for !stack.Empty() {
tok := stack.Pop()
if tok.LP() {
out <- Token{
Token: token.ILLEGAL,
Literal: "no closing parenthesis",
Pos: tok.Pos,
}
} else {
out <- tok
}
}
close(out)
}()
for tok := range in {
switch {
case tok.Token == token.ILLEGAL:
return
case tok.IsNumber():
out <- tok
case tok.IsFunc():
stack.Push(tok)
case tok.IsSeparator():
for {
if stack.Empty() {
out <- Token{
Token: token.ILLEGAL,
Literal: "no opening parenthesis",
Pos: tok.Pos,
}
return
}
if stack.Head().LP() {
break
}
out <- tok
}
case tok.IsOperator():
op1 := e.operators[tok.Token]
for {
if stack.Empty() {
break
}
if stack.Head().IsOperator() {
op2, hasOp := e.operators[stack.Head().Token]
if !hasOp {
out <- Token{
Token: token.ILLEGAL,
Literal: fmt.Sprintf("unknown operator: %s", stack.Head().Literal),
Pos: tok.Pos,
}
return
}
if op2.priority > op1.priority {
out <- stack.Pop()
continue
} else {
break
}
} else {
break
}
}
stack.Push(tok)
case tok.LP():
stack.Push(tok)
case tok.RP():
for {
if stack.Empty() {
out <- Token{
Token: token.ILLEGAL,
Literal: "no opening parenthesis",
Pos: tok.Pos,
}
return
}
if stack.Head().LP() {
break
}
out <- tok
}
stack.Pop()
if stack.Head().IsFunc() {
out <- stack.Pop()
}
}
}
}()
return out
}
|