blob: 2973f91c6488fadd8696444e546513314eecd98f [file] [log] [blame]
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +09001package main
2
3type Var interface {
4 Value
5 Flavor() string
6 Origin() string
7 IsDefined() bool
8}
9
10type Value interface {
11 String() string
12 Eval(ev *Evaluator) string
Fumitoshi Ukaic1847602015-04-02 16:18:02 +090013 Append(*Evaluator, string) Var
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090014}
15
16type SimpleVar struct {
17 value string
18 origin string
19}
20
21func (v SimpleVar) Flavor() string { return "simple" }
22func (v SimpleVar) Origin() string { return v.origin }
23func (v SimpleVar) IsDefined() bool { return true }
24
25func (v SimpleVar) String() string { return v.value }
26func (v SimpleVar) Eval(ev *Evaluator) string { return v.value }
Fumitoshi Ukaic1847602015-04-02 16:18:02 +090027func (v SimpleVar) Append(ev *Evaluator, s string) Var {
28 v.value += " " + ev.evalExpr(s)
29 return v
30}
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090031
32type RecursiveVar struct {
33 expr string
34 origin string
35}
36
37func (v RecursiveVar) Flavor() string { return "recursive" }
38func (v RecursiveVar) Origin() string { return v.origin }
39func (v RecursiveVar) IsDefined() bool { return true }
Fumitoshi Ukaic1847602015-04-02 16:18:02 +090040
41func (v RecursiveVar) String() string { return v.expr }
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090042func (v RecursiveVar) Eval(ev *Evaluator) string {
43 return ev.evalExpr(v.expr)
44}
Fumitoshi Ukaic1847602015-04-02 16:18:02 +090045func (v RecursiveVar) Append(_ *Evaluator, s string) Var {
46 v.expr += " " + s
47 return v
48}
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090049
50type UndefinedVar struct{}
51
Fumitoshi Ukaic1847602015-04-02 16:18:02 +090052func (_ UndefinedVar) Flavor() string { return "undefined" }
Shinichiro Hamaji7ff34db2015-04-04 18:55:20 +090053func (_ UndefinedVar) Origin() string { return "undefined" }
Fumitoshi Ukaic1847602015-04-02 16:18:02 +090054func (_ UndefinedVar) IsDefined() bool { return false }
55func (_ UndefinedVar) String() string { return "" }
56func (_ UndefinedVar) Eval(ev *Evaluator) string {
57 return ""
58}
59func (_ UndefinedVar) Append(*Evaluator, string) Var {
60 return UndefinedVar{}
61}
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090062
63type VarTab struct {
64 m map[string]Var
65 parent *VarTab
66}
67
68func NewVarTab(vt *VarTab) *VarTab {
69 return &VarTab{
70 m: make(map[string]Var),
71 parent: vt,
72 }
73}
74
75func (vt *VarTab) Vars() map[string]Var {
76 m := make(map[string]Var)
77 if vt.parent != nil {
78 for k, v := range vt.parent.Vars() {
79 m[k] = v
80 }
81 }
82 for k, v := range vt.m {
83 m[k] = v
84 }
85 return m
86}
87
88func (vt *VarTab) Lookup(name string) Var {
89 if v, ok := vt.m[name]; ok {
90 return v
91 }
92 if vt.parent != nil {
93 return vt.parent.Lookup(name)
94 }
95 return UndefinedVar{}
96}
97
98func (vt *VarTab) Assign(name string, v Var) {
99 vt.m[name] = v
100}