rising-sse 0.1.dev0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rising_sse-0.1.dev0.dist-info/METADATA +7 -0
- rising_sse-0.1.dev0.dist-info/RECORD +7 -0
- rising_sse-0.1.dev0.dist-info/WHEEL +5 -0
- sse/__init__.py +17 -0
- sse/engine.py +214 -0
- sse/mode.py +191 -0
- sse/parser.py +126 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
sse/__init__.py,sha256=315hdFuiClzekzr65spyTUFfWhlTY3Y9uOe0zVEL5lY,723
|
|
2
|
+
sse/engine.py,sha256=ENr4NwkTcs5osMYzDE5qndAWc2yEqdq6GnpEHwjUd_U,8836
|
|
3
|
+
sse/mode.py,sha256=Hf7YgWxhxsTZFpuHJL8fKyrocRNGdarJTUrytpnoFcI,5879
|
|
4
|
+
sse/parser.py,sha256=tA0YPcqhng3DQKR1CJXluHs-PBTEGYLlFzSxajDaRMU,3215
|
|
5
|
+
rising_sse-0.1.dev0.dist-info/METADATA,sha256=kYPiwjyXDEz5mKIX3cZ-NbB8aJDHyKXJuWYY7dfQrnc,239
|
|
6
|
+
rising_sse-0.1.dev0.dist-info/WHEEL,sha256=VX-VJ7c6dw9Ge3EqJIbA6W3pOUbz24SnnGGFNr55jY4,105
|
|
7
|
+
rising_sse-0.1.dev0.dist-info/RECORD,,
|
sse/__init__.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from .engine import Engine, run
|
|
2
|
+
from .mode import Mode, GetMode, primitive, prompt
|
|
3
|
+
|
|
4
|
+
def basic_engine():
|
|
5
|
+
"""
|
|
6
|
+
call this function if you just want to play around with the base form of the engine
|
|
7
|
+
without modifying or extending its functionality or hooking it into an API or game.
|
|
8
|
+
Otherwise, you can create an instance of the engine using Engine(), and start it by calling run()
|
|
9
|
+
on it, or ticking it within your own loop function.
|
|
10
|
+
To retrieve any mode use its modename in GetMode(modename:str).
|
|
11
|
+
To create a mode use Mode(modename:str, available:bool=True), set available to False to hide it
|
|
12
|
+
from GetMode
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
semantic_syntax_engine = Engine()
|
|
16
|
+
run(semantic_syntax_engine)
|
|
17
|
+
|
sse/engine.py
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
from .mode import GetMode, default_globals
|
|
2
|
+
from .parser import tokenize
|
|
3
|
+
|
|
4
|
+
class Engine:
|
|
5
|
+
__slots__ = ("frame_stack", "running", "engine_globals", "mode")
|
|
6
|
+
def __init__(self, starter = GetMode('main'), engine_globals = default_globals):
|
|
7
|
+
self.frame_stack = []
|
|
8
|
+
self.running = False
|
|
9
|
+
self.mode = starter
|
|
10
|
+
self.engine_globals = engine_globals
|
|
11
|
+
@property
|
|
12
|
+
def frame(self):
|
|
13
|
+
return self.frame_stack[-1]
|
|
14
|
+
def tick(self):
|
|
15
|
+
|
|
16
|
+
if len(self.frame_stack) > 0:
|
|
17
|
+
# get the engines current frame
|
|
18
|
+
frame = self.frame
|
|
19
|
+
|
|
20
|
+
# extract the frames mode
|
|
21
|
+
mode = frame['mode']
|
|
22
|
+
# the frames positions
|
|
23
|
+
line_position = frame['line_position']
|
|
24
|
+
element_position = frame['element_position']
|
|
25
|
+
|
|
26
|
+
# the frames instructions
|
|
27
|
+
instructions = frame['instructions']
|
|
28
|
+
# the frames scope and the frames stack
|
|
29
|
+
scope = frame['scope']
|
|
30
|
+
stack = frame['stack']
|
|
31
|
+
|
|
32
|
+
engine_globals = self.engine_globals
|
|
33
|
+
|
|
34
|
+
if line_position >= len(instructions):
|
|
35
|
+
previous_frame = self.frame_stack.pop()
|
|
36
|
+
else:
|
|
37
|
+
# get the current line and element
|
|
38
|
+
current_line = instructions[line_position]
|
|
39
|
+
if element_position is None:
|
|
40
|
+
element_position = len(current_line) - 1
|
|
41
|
+
current_element = current_line[element_position]
|
|
42
|
+
frame['element_position'] = element_position
|
|
43
|
+
|
|
44
|
+
# TICK LOGIC
|
|
45
|
+
self.handle_element(current_element, frame, mode, scope, stack)
|
|
46
|
+
|
|
47
|
+
# increment positions
|
|
48
|
+
element_position = frame['element_position']
|
|
49
|
+
element_position -= 1
|
|
50
|
+
if element_position <= -1:
|
|
51
|
+
element_position = None
|
|
52
|
+
line_position += 1
|
|
53
|
+
frame['line_position'] = line_position
|
|
54
|
+
stack.clear()
|
|
55
|
+
frame['element_position'] = element_position
|
|
56
|
+
|
|
57
|
+
else:
|
|
58
|
+
mode = self.mode
|
|
59
|
+
if 'prompt' in mode:
|
|
60
|
+
mode['prompt'](mode)
|
|
61
|
+
else:
|
|
62
|
+
self.engine_globals["prompt"](mode)
|
|
63
|
+
usertext = input()
|
|
64
|
+
code = tokenize(self.structure_input(usertext))
|
|
65
|
+
frame = self.Frame(mode, mode['main'], code)
|
|
66
|
+
self.AddFrame(frame)
|
|
67
|
+
|
|
68
|
+
def handle_element(self, current_element, frame, mode, scope, stack):
|
|
69
|
+
element_type, value = current_element
|
|
70
|
+
|
|
71
|
+
engine_globals = self.engine_globals
|
|
72
|
+
|
|
73
|
+
match element_type:
|
|
74
|
+
case "string" | "integer" | "float" | "rawtoken" | "dotchain":
|
|
75
|
+
stack.append(value)
|
|
76
|
+
case "primitive":
|
|
77
|
+
mode_primitives = mode['primitives']
|
|
78
|
+
global_primitives = engine_globals['primitives']
|
|
79
|
+
if value in mode_primitives:
|
|
80
|
+
mode_primitives[value](frame, self, stack)
|
|
81
|
+
elif value in global_primitives:
|
|
82
|
+
global_primitives[value](frame, self, stack)
|
|
83
|
+
else:
|
|
84
|
+
self.error(f"There is no available primitive called '{value}'.", "Missing Primitive")
|
|
85
|
+
case "intentive":
|
|
86
|
+
if len(stack) > 0:
|
|
87
|
+
intent = stack.pop()
|
|
88
|
+
if isinstance(intent, list):
|
|
89
|
+
intent = intent[::-1]
|
|
90
|
+
mode_primitives = mode['primitives']
|
|
91
|
+
global_primitives = engine_globals['primitives']
|
|
92
|
+
if value in mode_primitives:
|
|
93
|
+
mode_primitives[value](frame, self, intent)
|
|
94
|
+
elif value in global_primitives:
|
|
95
|
+
global_primitives[value](frame, self, intent)
|
|
96
|
+
else:
|
|
97
|
+
self.error(f"There is no available primitive called '{value}'.", "Missing Primitive")
|
|
98
|
+
else:
|
|
99
|
+
self.error(f"Intentive primitive expects a stack not {intent}.", "Incorrect Intent")
|
|
100
|
+
else:
|
|
101
|
+
self.error(f"No available intentive stack.", "Missing Intent")
|
|
102
|
+
case "set_var":
|
|
103
|
+
set_val = stack.pop()
|
|
104
|
+
|
|
105
|
+
# find the start of the path
|
|
106
|
+
# only set in current_scope
|
|
107
|
+
current_scope = scope
|
|
108
|
+
|
|
109
|
+
for link in value[:-1]:
|
|
110
|
+
if link in current_scope:
|
|
111
|
+
current_scope = current_scope[link]
|
|
112
|
+
else:
|
|
113
|
+
self.error(f"Could not follow the path {value} past '{link}'.", "Missing Link")
|
|
114
|
+
break
|
|
115
|
+
else:
|
|
116
|
+
current_scope[value[-1]] = set_val
|
|
117
|
+
|
|
118
|
+
case "get_var":
|
|
119
|
+
start, path = value[0], value[1:]
|
|
120
|
+
|
|
121
|
+
current_scope = scope
|
|
122
|
+
nonlocal_scope = current_scope if '__nonlocal__' in current_scope else current_scope
|
|
123
|
+
global_scope = engine_globals['main']
|
|
124
|
+
|
|
125
|
+
# find the start of the path
|
|
126
|
+
# prioritize current_scope -> nonlocal_scope -> global_scope
|
|
127
|
+
getting = None
|
|
128
|
+
if start in current_scope:
|
|
129
|
+
getting = current_scope[start]
|
|
130
|
+
elif start in nonlocal_scope:
|
|
131
|
+
getting = nonlocal_scope[start]
|
|
132
|
+
elif start in global_scope:
|
|
133
|
+
getting = global_scope[start]
|
|
134
|
+
else:
|
|
135
|
+
self.error(f"There is no available variable called '{start}'.", "Missing Variable")
|
|
136
|
+
if getting is not None:
|
|
137
|
+
if len(path) > 0:
|
|
138
|
+
for link in path:
|
|
139
|
+
if link in getting:
|
|
140
|
+
getting = getting[link]
|
|
141
|
+
else:
|
|
142
|
+
self.error(f"Could not follow the path {path} from {start} past '{link}'.", "Missing Link")
|
|
143
|
+
getting = None
|
|
144
|
+
break
|
|
145
|
+
if getting is not None:
|
|
146
|
+
stack.append(getting)
|
|
147
|
+
else:
|
|
148
|
+
stack.append(getting)
|
|
149
|
+
case "stack":
|
|
150
|
+
new_stack = []
|
|
151
|
+
for element in value[::-1]:
|
|
152
|
+
self.handle_element(element, frame, mode, scope, new_stack)
|
|
153
|
+
stack.append(new_stack[::-1])
|
|
154
|
+
case "block":
|
|
155
|
+
stack.append({"__instructions__":value})
|
|
156
|
+
case other:
|
|
157
|
+
print(other, value)
|
|
158
|
+
|
|
159
|
+
@staticmethod
|
|
160
|
+
def Frame(mode, scope, instructions):
|
|
161
|
+
return {
|
|
162
|
+
"mode":mode,
|
|
163
|
+
"line_position":0,
|
|
164
|
+
"element_position":None,
|
|
165
|
+
"scope":scope,
|
|
166
|
+
"instructions":instructions,
|
|
167
|
+
"stack":[]
|
|
168
|
+
}
|
|
169
|
+
def AddFrame(self, frame):
|
|
170
|
+
self.frame_stack.append(frame)
|
|
171
|
+
def say(self, message:str, name:str="Semantic Syntax Engine"):
|
|
172
|
+
print(f"[{name}]: {message}")
|
|
173
|
+
def announce(self, message:str):
|
|
174
|
+
print(message)
|
|
175
|
+
def error(self, message:str, errortype:str="Exception"):
|
|
176
|
+
self.say(f"({errortype}) {message}")
|
|
177
|
+
|
|
178
|
+
def structure_input(self, usertext:str, section_start:str="[", section_end:str="]"):# -> list:
|
|
179
|
+
index = 0
|
|
180
|
+
section = ""
|
|
181
|
+
depth = 0
|
|
182
|
+
sections = []
|
|
183
|
+
while index < len(usertext):
|
|
184
|
+
char = usertext[index]
|
|
185
|
+
if char == section_start:
|
|
186
|
+
if depth > 0:
|
|
187
|
+
section += char
|
|
188
|
+
depth += 1
|
|
189
|
+
|
|
190
|
+
elif char == section_end:
|
|
191
|
+
if depth == 0:
|
|
192
|
+
raise Exception(f"No starting '[' to ']' at character {index}")
|
|
193
|
+
elif depth == 1:
|
|
194
|
+
sections.append(section)
|
|
195
|
+
section = ""
|
|
196
|
+
elif depth > 1:
|
|
197
|
+
section += char
|
|
198
|
+
|
|
199
|
+
depth -= 1
|
|
200
|
+
else:
|
|
201
|
+
if depth > 0:
|
|
202
|
+
section += char
|
|
203
|
+
index += 1
|
|
204
|
+
return "; ".join(sections)
|
|
205
|
+
def SetMode(self, modename:str):
|
|
206
|
+
mode = GetMode(modename)
|
|
207
|
+
if mode is not None:
|
|
208
|
+
self.mode = mode
|
|
209
|
+
else:
|
|
210
|
+
self.error(f"There is no available mode called {modename}", "Missing Mode")
|
|
211
|
+
def run(engine:Engine):
|
|
212
|
+
engine.running = True
|
|
213
|
+
while engine.running:
|
|
214
|
+
engine.tick()
|
sse/mode.py
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"""
|
|
2
|
+
In the Semantic Syntax Engine a mode is a module of the language
|
|
3
|
+
the engine will use its mode to determine how to interpret Semantic Syntax
|
|
4
|
+
switching out modules is like switching to an entirely new set of tools
|
|
5
|
+
while the basic structure remains the same
|
|
6
|
+
"""
|
|
7
|
+
from .parser import tokenize
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
__modes = {}
|
|
11
|
+
|
|
12
|
+
def Mode(modename:str, available:bool=True):
|
|
13
|
+
mode = {
|
|
14
|
+
"name":modename,
|
|
15
|
+
"primitives":{},
|
|
16
|
+
"main":{},
|
|
17
|
+
}
|
|
18
|
+
if available:
|
|
19
|
+
__modes[modename] = mode
|
|
20
|
+
return mode
|
|
21
|
+
|
|
22
|
+
def GetMode(modename:str):
|
|
23
|
+
if modename in __modes:
|
|
24
|
+
return __modes[modename]
|
|
25
|
+
else:
|
|
26
|
+
return None
|
|
27
|
+
|
|
28
|
+
def primitive(mode, name):
|
|
29
|
+
def wrap(method):
|
|
30
|
+
mode['primitives'][name] = method
|
|
31
|
+
return wrap
|
|
32
|
+
|
|
33
|
+
def prompt(mode):
|
|
34
|
+
def wrap(method):
|
|
35
|
+
mode['prompt'] = method
|
|
36
|
+
return wrap
|
|
37
|
+
|
|
38
|
+
# the default mode for globals that are accessible in any other mode (can be changed)
|
|
39
|
+
default_globals = Mode('default_globals', False)
|
|
40
|
+
main = Mode('main')
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@prompt(default_globals)
|
|
44
|
+
def _prompt(self):
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# OUTPUT
|
|
49
|
+
@primitive(default_globals, "print")
|
|
50
|
+
def _print(frame, engine, stack):
|
|
51
|
+
output = " ".join(str(element) for element in stack[::-1])
|
|
52
|
+
print(output)
|
|
53
|
+
if not output.endswith('\n'):
|
|
54
|
+
print()
|
|
55
|
+
|
|
56
|
+
stack.clear()
|
|
57
|
+
|
|
58
|
+
# MATHEMATICS
|
|
59
|
+
@primitive(default_globals, "add")
|
|
60
|
+
def add(frame, engine, stack):
|
|
61
|
+
obj_a = stack.pop()
|
|
62
|
+
obj_b = stack.pop()
|
|
63
|
+
stack.append(obj_a + obj_b)
|
|
64
|
+
@primitive(default_globals, "sub")
|
|
65
|
+
def subtract(frame, engine, stack):
|
|
66
|
+
obj_a = stack.pop()
|
|
67
|
+
obj_b = stack.pop()
|
|
68
|
+
stack.append(obj_a - obj_b)
|
|
69
|
+
@primitive(default_globals, "mul")
|
|
70
|
+
def multiply(frame, engine, stack):
|
|
71
|
+
obj_a = stack.pop()
|
|
72
|
+
obj_b = stack.pop()
|
|
73
|
+
stack.append(obj_a * obj_b)
|
|
74
|
+
@primitive(default_globals, "div")
|
|
75
|
+
def divide(frame, engine, stack):
|
|
76
|
+
obj_a = stack.pop()
|
|
77
|
+
obj_b = stack.pop()
|
|
78
|
+
stack.append(obj_a / obj_b)
|
|
79
|
+
|
|
80
|
+
# STACK
|
|
81
|
+
@primitive(default_globals, "Stack")
|
|
82
|
+
def create_stack(frame, engine, stack):
|
|
83
|
+
new_stack = stack[::-1]
|
|
84
|
+
stack.clear()
|
|
85
|
+
stack.append(new_stack)
|
|
86
|
+
@primitive(default_globals, "pull")
|
|
87
|
+
def pull_stack(frame, engine, stack):
|
|
88
|
+
_stack = stack[-1]
|
|
89
|
+
stack.append(_stack.pop(0))
|
|
90
|
+
@primitive(default_globals, "push")
|
|
91
|
+
def push_stack(frame, engine, stack):
|
|
92
|
+
value = stack.pop()
|
|
93
|
+
_stack = stack[-1]
|
|
94
|
+
_stack.insert(0, value)
|
|
95
|
+
|
|
96
|
+
# BLOCK
|
|
97
|
+
@primitive(default_globals, "Block") # create an empty block
|
|
98
|
+
def create_block(frame, engine, stack):
|
|
99
|
+
new_block = {}
|
|
100
|
+
stack.append(new_block)
|
|
101
|
+
@primitive(default_globals, "def") # add parameters to a block
|
|
102
|
+
def define(frame, engine, stack):
|
|
103
|
+
parameters = stack.pop()
|
|
104
|
+
obj = stack.pop()
|
|
105
|
+
if '__instructions__' in obj:
|
|
106
|
+
obj['__params__'] = parameters
|
|
107
|
+
stack.append(obj)
|
|
108
|
+
else:
|
|
109
|
+
engine.error(f"Cannot add parameters to {obj}", "Incallable Object")
|
|
110
|
+
@primitive(default_globals, "call") # call a block
|
|
111
|
+
def call(frame, engine, stack):
|
|
112
|
+
obj = stack.pop()
|
|
113
|
+
if '__instructions__' in obj:
|
|
114
|
+
params = obj.get('__params__', tuple())
|
|
115
|
+
for param in params:
|
|
116
|
+
if len(stack) > 0:
|
|
117
|
+
argument = stack.pop()
|
|
118
|
+
obj[param] = argument
|
|
119
|
+
else:
|
|
120
|
+
engine.error(f"Failed to call {obj}", "Insifficient Arguments")
|
|
121
|
+
break
|
|
122
|
+
else:
|
|
123
|
+
new_frame = engine.Frame(frame['mode'], obj, obj['__instructions__'])
|
|
124
|
+
engine.AddFrame(new_frame)
|
|
125
|
+
else:
|
|
126
|
+
engine.error(f"Cannot call {obj}", "Incallable Object")
|
|
127
|
+
@primitive(default_globals, "return") # return a value
|
|
128
|
+
def return_value(frame, engine, stack):
|
|
129
|
+
if len(engine.frame_stack) > 1:
|
|
130
|
+
engine.frame_stack[-2]['stack'].append(stack.pop())
|
|
131
|
+
engine.frame_stack.pop()
|
|
132
|
+
@primitive(default_globals, "yield") # return a value without stopping
|
|
133
|
+
def return_value(frame, engine, stack):
|
|
134
|
+
if len(engine.frame_stack) > 1:
|
|
135
|
+
engine.frame_stack[-2]['stack'].append(stack.pop())
|
|
136
|
+
@primitive(default_globals, "script") # import a .sse file as a block
|
|
137
|
+
def script(frame, engine, stack):
|
|
138
|
+
dotchain = stack.pop()
|
|
139
|
+
if not isinstance(dotchain, str):
|
|
140
|
+
dotchain = "/".join(dotchain)
|
|
141
|
+
filepath = dotchain + ".sse"
|
|
142
|
+
if os.path.exists(filepath):
|
|
143
|
+
with open(filepath) as file:
|
|
144
|
+
code = file.read()
|
|
145
|
+
stack.append({'__instructions__':tokenize(code)})
|
|
146
|
+
else:
|
|
147
|
+
engine.error(f"Could not load script '{filepath}'.", "Missing File")
|
|
148
|
+
|
|
149
|
+
# CONTROL FLOW
|
|
150
|
+
@primitive(default_globals, "line") # get the current line as an integer
|
|
151
|
+
def get_current_line(frame, engine, stack):
|
|
152
|
+
stack.append(frame['line_position'])
|
|
153
|
+
@primitive(default_globals, "goto") # goto a given line
|
|
154
|
+
def goto_line(frame, engine, stack):
|
|
155
|
+
line_position = stack.pop()
|
|
156
|
+
engine.frame_stack.pop()
|
|
157
|
+
new_frame = engine.Frame(frame['mode'], frame['scope'], frame['instructions'])
|
|
158
|
+
new_frame['line_position'] = line_position
|
|
159
|
+
engine.AddFrame(new_frame)
|
|
160
|
+
@primitive(default_globals, "if")
|
|
161
|
+
def if_statement(frame, engine, stack):
|
|
162
|
+
if len(stack) > 0:
|
|
163
|
+
if stack.pop():
|
|
164
|
+
return
|
|
165
|
+
frame['element_position'] = 0
|
|
166
|
+
@primitive(default_globals, "not")
|
|
167
|
+
def _not(frame, engine, stack):
|
|
168
|
+
if len(stack) > 0:
|
|
169
|
+
stack.append(not stack.pop())
|
|
170
|
+
else:
|
|
171
|
+
stack.append(True)
|
|
172
|
+
@primitive(default_globals, "True")
|
|
173
|
+
def true(frame, engine, stack):
|
|
174
|
+
stack.append(True)
|
|
175
|
+
@primitive(default_globals, "False")
|
|
176
|
+
def false(frame, engine, stack):
|
|
177
|
+
stack.append(False)
|
|
178
|
+
|
|
179
|
+
@primitive(default_globals, "mode")
|
|
180
|
+
def get_mode_name(frame, engine, stack):
|
|
181
|
+
stack.insert(0, frame['mode']['name'])
|
|
182
|
+
@primitive(default_globals, "setmode")
|
|
183
|
+
def set_mode(frame, engine, stack):
|
|
184
|
+
modename = stack.pop()
|
|
185
|
+
engine.SetMode(modename)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
sse/parser.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
from lark import Lark, Transformer, Discard
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
ss_structure = r"""
|
|
5
|
+
|
|
6
|
+
%import common.WS
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
ws: WS ?
|
|
11
|
+
|
|
12
|
+
start: ws (line (";" line)*) ? ws
|
|
13
|
+
|
|
14
|
+
line: ws (element (WS element)*) ? ws
|
|
15
|
+
|
|
16
|
+
element: STRING | NUMBER | rawtoken | stack | block | primitive | intentive | get_var | set_var | dotchain
|
|
17
|
+
|
|
18
|
+
%import common.ESCAPED_STRING -> STRING
|
|
19
|
+
%import common.SIGNED_NUMBER -> NUMBER
|
|
20
|
+
RAWTOKEN: /[a-zA-Z_][a-zA-Z0-9_-]*/
|
|
21
|
+
rawtoken: RAWTOKEN
|
|
22
|
+
|
|
23
|
+
stack: "[" line "]"
|
|
24
|
+
block: "{" start "}"
|
|
25
|
+
|
|
26
|
+
primitive: "/" RAWTOKEN
|
|
27
|
+
intentive: RAWTOKEN ws "->"
|
|
28
|
+
|
|
29
|
+
rawchain: (RAWTOKEN ("." RAWTOKEN)*) | ("." RAWTOKEN ("." RAWTOKEN)*) | (RAWTOKEN "." (RAWTOKEN ".")*) | ("." RAWTOKEN "." (RAWTOKEN ".")*) | (".")
|
|
30
|
+
dotchain: rawchain
|
|
31
|
+
|
|
32
|
+
get_var: rawchain "?"
|
|
33
|
+
set_var: rawchain ":"
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
class SS_Builder(Transformer):
|
|
38
|
+
def ws(self, ws):
|
|
39
|
+
return Discard
|
|
40
|
+
def WS(self, WS):
|
|
41
|
+
return Discard
|
|
42
|
+
def start(self, lines):
|
|
43
|
+
return tuple(lines)
|
|
44
|
+
def line(self, elements):
|
|
45
|
+
if len(elements) < 1:
|
|
46
|
+
return Discard
|
|
47
|
+
return tuple(elements)
|
|
48
|
+
def element(self, element):
|
|
49
|
+
return element[0]
|
|
50
|
+
def STRING(self, string):
|
|
51
|
+
return ("string", string[1:-1])
|
|
52
|
+
def NUMBER(self, number):
|
|
53
|
+
if '.' in number:
|
|
54
|
+
return ("float", float(number))
|
|
55
|
+
else:
|
|
56
|
+
return ("integer", int(number))
|
|
57
|
+
def RAWTOKEN(self, rawtoken):
|
|
58
|
+
return rawtoken[:]
|
|
59
|
+
def rawtoken(self, rawtoken):
|
|
60
|
+
return ("string", rawtoken[0])
|
|
61
|
+
def stack(self, stack):
|
|
62
|
+
if len(stack) >= 1:
|
|
63
|
+
return ("stack", stack[0])
|
|
64
|
+
else:
|
|
65
|
+
return ("stack", [])
|
|
66
|
+
def block(self, instructions):
|
|
67
|
+
if len(instructions) > 0:
|
|
68
|
+
return ("block", instructions[0])
|
|
69
|
+
else:
|
|
70
|
+
return ("block", tuple())
|
|
71
|
+
def primitive(self, primitive):
|
|
72
|
+
return ("primitive", primitive[0])
|
|
73
|
+
def intentive(self, primitive):
|
|
74
|
+
return ("intentive", primitive[0])
|
|
75
|
+
def rawchain(self, RAWTOKENS):
|
|
76
|
+
return tuple(RAWTOKENS)
|
|
77
|
+
def dotchain(self, rawchain):
|
|
78
|
+
return ("dotchain",rawchain[0])
|
|
79
|
+
|
|
80
|
+
def get_var(self, get_var):
|
|
81
|
+
return ("get_var", get_var[0])
|
|
82
|
+
def set_var(self, set_var):
|
|
83
|
+
return ("set_var", set_var[0])
|
|
84
|
+
ss_parser = Lark(ss_structure)
|
|
85
|
+
ss_builder = SS_Builder()
|
|
86
|
+
|
|
87
|
+
def tokenize(ss:str):
|
|
88
|
+
ss_tree = ss_parser.parse(ss)
|
|
89
|
+
ss_tokens = ss_builder.transform(ss_tree)
|
|
90
|
+
return ss_tokens
|
|
91
|
+
|
|
92
|
+
if __name__ == '__main__':
|
|
93
|
+
string_example = """
|
|
94
|
+
"here is a string" "and another"
|
|
95
|
+
"""
|
|
96
|
+
print(tokenize(string_example))
|
|
97
|
+
number_example = """
|
|
98
|
+
0.1 0 9 3 1.335
|
|
99
|
+
"""
|
|
100
|
+
tokenize(number_example)
|
|
101
|
+
rawtoken_example = """
|
|
102
|
+
hello_wha-t9_
|
|
103
|
+
"""
|
|
104
|
+
tokenize(rawtoken_example)
|
|
105
|
+
var_example = """
|
|
106
|
+
x: 0; x?;
|
|
107
|
+
x.x: 7;
|
|
108
|
+
"""
|
|
109
|
+
print(tokenize(var_example))
|
|
110
|
+
stack_example = """
|
|
111
|
+
[0 hello_wow "heres a string in a stack"]
|
|
112
|
+
"""
|
|
113
|
+
print(tokenize(stack_example))
|
|
114
|
+
block_example = """
|
|
115
|
+
{x 0 x-1;2.4 "string baby" i-1000}
|
|
116
|
+
"""
|
|
117
|
+
print(tokenize(block_example))
|
|
118
|
+
primitive_example = """
|
|
119
|
+
~prim
|
|
120
|
+
"""
|
|
121
|
+
print(tokenize(primitive_example))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|