-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompiler.py
More file actions
134 lines (105 loc) · 4.72 KB
/
compiler.py
File metadata and controls
134 lines (105 loc) · 4.72 KB
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
import re
import json
import argparse
import time
# Remove all newlines and white-spaces
def deconstruct_code(code):
code = re.sub(' *', '', code)
return code.split('\n')
# Global variable for complete compiled html code
complete_html = []
# Function for compiling .hv files
def compile(decon_hv_code):
# Variable for runtime block ending saves
block_ends = []
for unit in decon_code:
# If white-space, newline or comment detected
if unit == '' or unit == '\n' or unit[0:2] == '//':
# Ignore
continue
# If end-of-block detected
if unit[0] == '}':
# Pop the latest block end from the stack and add it to the complete html code
complete_html.append(block_ends.pop())
continue
# If start of the block detected
if unit[-1] == '{':
# Parse the block name
block_name = re.findall('^[a-z]*\[', unit)[0]
block_name = re.sub('\[', '', block_name)
# Parse the block attributes
block_attrs = re.findall('\[\{.*\}\]', unit)[0]
block_attrs = re.sub('(\[|\])', '', block_attrs)
block_attrs = json.loads(block_attrs)
block_attrs_string = ""
# Join it all in a string
for i in block_attrs:
block_attrs_string += f'{i}="{block_attrs[i]}" '
# Remove the end white-space
block_attrs_string = block_attrs_string[0:-1]
# If no attributes are passed, don't add it. Else - add the attr field
if not block_attrs_string == '':
complete_html.append(f"<{block_name} {block_attrs_string}>\n")
else:
complete_html.append(f"<{block_name}>\n")
# Add the ending of the block to the stack
block_ends.append(f'</{block_name}>\n')
continue
# If oneliner detected
if re.match('[a-zA-Z0-9].*\](\{.*\}|)', unit) or unit[0] == '"' and unit[-1] == '"':
# Check, if regular text has been passed in
if unit[0] == '"' and unit[-1] == '"':
text = re.findall('".*"', unit)[0]
complete_html.append(text + '\n')
continue
# Parse the block name
block_name = re.findall('^[a-z]*\[', unit)[0]
block_name = re.sub('\[', '', block_name)
# Parse the block attributes
block_attrs = re.findall('\[\{.*\}\]', unit)[0]
block_attrs = re.sub('(\[|\])', '', block_attrs)
block_attrs = json.loads(block_attrs)
block_attrs_string = ""
# Join it all in a string
for i in block_attrs:
block_attrs_string += f'{i}="{block_attrs[i]}" '
# Remove the end white-space
block_attrs_string = block_attrs_string[0:-1]
# Parse content
content = re.findall('\]\{".*\}$', unit)
# If content exists, add it. Else - dont add the field
if content:
block_content = re.sub('(\]|\{|\}|")', '', content[0])
# If no attributes are passed, don't add it. Else - add the attr field
if not block_attrs_string == '':
complete_html.append(f'<{block_name} {block_attrs_string}>{block_content}</{block_name}>\n')
else:
complete_html.append(f'<{block_name}>{block_content}</{block_name}>\n')
continue
# If no attributes are passed, don't add it. Else - add the attr field
if unit[-1] == ']':
if not block_attrs_string == '':
complete_html.append(f'<{block_name} {block_attrs_string}>\n')
else:
complete_html.append(f'<{block_name}>\n')
continue
# If there are no rule, that can catch the unit, throw a message and continue parsing.
print(f"!![COMPILE_ERROR]: Unit '{unit}' cannot be compiled!")
continue
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('INPUT', metavar='INPUT', type=str,
help='Path to .hv file (source code)')
parser.add_argument('OUTPUT', metavar='OUTPUT', type=str,
help='Path and name of the output file')
args = parser.parse_args()
start_time = time.time()
with open(args.INPUT, 'r') as f:
raw_code = f.read()
decon_code = deconstruct_code(raw_code)
#print(decon_code)
compile(decon_code)
with open(args.OUTPUT, 'w') as f:
f.writelines(complete_html)
print("Done!")
print(f"========= {time.time() - start_time} seconds =========")