-
Notifications
You must be signed in to change notification settings - Fork 0
/
compiler.py
executable file
·116 lines (92 loc) · 2.63 KB
/
compiler.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python3
import sys
'''bytecode compiler'''
if len(sys.argv)>1:
source=sys.argv[1]
else:
source='source.zsc'
try:
ifp=open(source, 'r')
except FileNotFoundError:
print(source, 'file not found')
sys.exit()
print('opened source file:', source)
if len(sys.argv)>2:
bytecode=sys.argv[2]
else:
bytecode='out.zbc'
ofp=open(bytecode, 'wb')
print('opened bytecode file:', bytecode)
# fields size specs
address_bytes_count=1
instruction_bytes_count=1
field_sizes = {0:address_bytes_count, 1:address_bytes_count, 2:instruction_bytes_count, 3:instruction_bytes_count}
# mapping
def max_value_bits(bytes_count):
return 2**(bytes_count*8)
address_max_value=max_value_bits(address_bytes_count)-1
instruction_max_value=max_value_bits(instruction_bytes_count)-1
mapping={'PATHSEL':address_max_value, 'ZERO':0, 'ONE':1, 'IN':address_max_value-1, 'OUT':address_max_value-1, 'EXIT': instruction_max_value}
'''
read from ORIGIN: PATHSEL(255), ZERO(0), ONE(1), IN(254), memory(rest...)
read-not from: OUT(254)
write to DESTINATION: PATHSEL(255), OUT(254), memory(rest...)
write-not to: ZERO(0), ONE(1), IN(254)
'''
#FIELD0 IS DESTINATION
field0_ok=['PATHSEL', 'OUT']
field0_not_ok=['ZERO', 'ONE', 'IN']
#FIELD1 IS ORIGIN
field1_ok=['PATHSEL', 'ZERO', 'ONE', 'IN']
field1_not_ok=['OUT']
#############
#ofp.write(bytes(field_sizes.values()))
for line in ifp:
line=line.rstrip("\n")
line=line.split("#")[0]
fields=line.split(',')
fields = [field.strip(' \t\n\r') for field in fields]
error = lambda why: print("wrong fields:",why, repr(fields))
if(['']==fields): continue
if(len(fields)!=4):
error('not 4')
if(len(fields)==3):
fields.append(fields[2])
continue
try:
def convert(i, field):
if('-'==field[0]):
field=field.lstrip('-')
if i==0: #field0
if field in field0_ok and field not in field0_not_ok:
pass
else:
error("field0 not ok")
elif i==1: #field1
if field in field1_ok and field not in field1_not_ok:
pass
else:
error("field1 not ok")
elif i in [2,3]:
pass
else:
error("field index not valid")
try:
field=mapping[field]
except KeyError:
error("field not mapped")
else:
field=int(field)
if(i in (0,1)):
field+=2
assert(field<=address_max_value)
return field
print('repr(fields) ', repr(fields))
fields=[convert(i,field) for i,field in enumerate(fields)]
except ValueError:
error('not int')
continue
print('fields ', fields)
for i,field in enumerate(fields):
ofp.write(field.to_bytes(field_sizes[i], byteorder='big'))
print("end of file scanning")