-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathliteral_gen.py
100 lines (83 loc) · 2.83 KB
/
literal_gen.py
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
from node.create_list import List
from node.numeric_literal import NumericLiteral
from node.string_literal import StringLiteral
from type.type_time import TypeTime
nodes = {int: NumericLiteral,
float: NumericLiteral,
str: StringLiteral,
list: List,
tuple: List}
def int_literal(number):
if number == 0:
return "0"
abs_num = abs(number)
is_neg = number < 0
return str(abs_num)+"_"*is_neg
def float_literal(number):
if number == 0:
return ".0"
abs_num = abs(number)
is_neg = number<0
less_one = abs_num < 1
return str(abs_num)[less_one:]+"_"*is_neg
def string_literal(string):
if len(string) == 1:
return "\\"+string
return '"'+string+'"'
def list_literal(seq):
end = List.char[:]
if len(seq) != List.default_arg:
end += bytearray(int_literal(len(seq)).encode("ascii"))
#print("LIST", seq, end)
return stack_literal(seq)+end
def tuple_literal(seq):
return list_literal(seq)
def time_literal(time): raise NotImplementedError()
def set_literal(seq): raise NotImplementedError()
def dict_literal(dic): raise NotImplementedError()
parsers = {int: int_literal,
float: float_literal,
str: string_literal,
list: list_literal,
tuple: tuple_literal,
set: set_literal,
dict: dict_literal,
TypeTime: time_literal}
def parse_item(item):
rtn = parsers[type(item)](item)
if isinstance(rtn, str):
return bytearray(rtn.encode("ascii"))
return rtn
def stack_literal(stack):
#print("STACK LITERAL", stack)
node_list = list(map(parse_item, stack))
#print("NODE LIST", node_list)
rtn = bytearray()
for i in range(len(node_list)-1):
rtn += node_list[i]
node_type = nodes[type(stack[i])]
node_type_next = nodes[type(stack[i+1])]
is_list = node_type_next is List
assert(node_type.accepts(node_list[i]))
code, node = node_type.accepts(node_list[i]+node_list[i+1])
#print("underscore", code)
if not code or code == b"_":
rtn += b" "
elif node_type is List and node_type_next is NumericLiteral:
rtn += b" "
elif is_list:
next_test_parsed = node_list[i+1]
next_test_str = stack[i+1]
while node_type_next is List:
next_test_parsed = next_test_parsed[:1]
next_test_str = next_test_str[0]
node_type_next = nodes[type(next_test_str)]
code, node = node_type.accepts(node_list[i]+next_test_parsed)
#print("empty", code)
if code == b"":
rtn += b" "
elif node_type is List and node_type_next is NumericLiteral:
rtn += b" "
if node_list:
rtn += bytearray(node_list[-1])
return rtn