-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmod.go
139 lines (119 loc) · 3.08 KB
/
mod.go
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"container/list"
"strings"
)
/*
* In shiba, there are 3 kinds of scope; global scope, function scope, and block scope.
* A module has global scope and the list of function scope. Global scope and function scope contains block scopes internally.
*
* Global scope is defined on loading module. It contains globally defined variable and functions. For example,
* ```
* a = 1
* def f() {
* b = 1
* }
* if true {
* c = 1
* if true {
* d = 1
* }
* }
* ```
* On the above code, global scope contains
*
* * variable a
* * function f
*
* Block scope is created when the code execution enters a block, such as if or for-loop.
* On the above code, the block scope in global scope will hold 2 blocks; one is for outer if-block, the other is for inner if-block.
* The block scope is defined as linked list. So actual look will be like [outer] -> [inner].
* This is because the variable/definition in outer block will be visible in inner block so they must be connected.
*
* Function scope is mostly the same as global scope itself, but the difference is that
* in a function scope, the gloval scope is also visible. e.g.
* ```
* a = 1
*
* def f2() {
* print(a)
* print(b) # not allowed
* c = 1
* }
*
* def f1() {
* print(a)
* b = 1
* f1()
* }
* ```
* In both f1 and f2, the global var a should be visible. Note that f2 is called from f1, but b in f1 must not be visible from f2.
*/
type module struct {
name string
filename string
directory string
content []rune
globscope *scope
funcscopes *list.List
}
func (m *module) createfuncscope() {
m.funcscopes.PushBack(newscope())
}
func (m *module) delfuncscope() {
m.funcscopes.Remove(m.funcscopes.Back())
}
func (m *module) createblockscope() {
if m.funcscopes.Len() != 0 {
m.funcscopes.Back().Value.(*scope).addblockscope()
return
}
m.globscope.addblockscope()
}
func (m *module) delblockscope() {
if m.funcscopes.Len() != 0 {
m.funcscopes.Back().Value.(*scope).addblockscope()
return
}
m.globscope.delblockscope()
}
func (m *module) setobj(name string, o *obj) {
if m.funcscopes.Len() != 0 {
m.funcscopes.Back().Value.(*scope).setobj(name, o)
return
}
m.globscope.setobj(name, o)
}
func (m *module) setstruct(name string, s *structdef) {
if m.funcscopes.Len() != 0 {
m.funcscopes.Back().Value.(*scope).setstruct(name, s)
return
}
m.globscope.setstruct(name, s)
}
func (m *module) getobj(name string) (*obj, bool) {
if m.funcscopes.Len() != 0 {
o, ok := m.funcscopes.Back().Value.(*scope).getobj(name)
if ok {
return o, true
}
return m.globscope.getglobobj(name)
}
return m.globscope.getobj(name)
}
func (m *module) getstruct(name string) (*structdef, bool) {
if m.funcscopes.Len() != 0 {
s, ok := m.funcscopes.Back().Value.(*scope).getstruct(name)
if ok {
return s, true
}
return m.globscope.getglobstruct(name)
}
return m.globscope.getstruct(name)
}
func modtofile(modname string) string {
return modname + ".sb"
}
func filetomod(filename string) string {
return strings.TrimSuffix(filename, ".sb")
}