bump
This commit is contained in:
20
Makefile
20
Makefile
@ -23,6 +23,8 @@ LDFLAGS += -lm
|
|||||||
|
|
||||||
OUT := eaxhla
|
OUT := eaxhla
|
||||||
|
|
||||||
|
PLUG := tool/plug
|
||||||
|
|
||||||
SOURCE.d := source
|
SOURCE.d := source
|
||||||
OBJECT.d := object
|
OBJECT.d := object
|
||||||
|
|
||||||
@ -67,26 +69,22 @@ bootstrap:
|
|||||||
./library/bootstrap.sh
|
./library/bootstrap.sh
|
||||||
|
|
||||||
test: ${OUT}
|
test: ${OUT}
|
||||||
#fcpp -C -LL debug/xop.eax > debug/xop.eax.pp
|
|
||||||
#${WRAP} ./${OUT} debug/xop.eax
|
#${WRAP} ./${OUT} debug/xop.eax
|
||||||
#./${OUT} debug/xop.eax # NOTE as of now broken, but only because of undefined instructions
|
|
||||||
#${WRAP} ./${OUT} debug/artimetrics.eax
|
|
||||||
#@echo -e "\033[31;1m --- ERROR TESTING BEGINS BELOW ---\033[0m"
|
|
||||||
#debug/error_test.sh
|
|
||||||
#./${OUT} debug/heyo_world.eax
|
|
||||||
ORIGIN="$$(realpath .)" PATH="$$(realpath .):${PATH}" cmdtest
|
ORIGIN="$$(realpath .)" PATH="$$(realpath .):${PATH}" cmdtest
|
||||||
|
|
||||||
clean:
|
clean: unplug
|
||||||
-rm ${OUT} ${OBJECT} ${GENOBJECT} ${GENSOURCE}
|
-rm ${OUT} ${OBJECT} ${GENOBJECT} ${GENSOURCE}
|
||||||
|
|
||||||
${OBJECT.d}/%.pp: debug/%.tcl debug/instructions.tcl
|
${OBJECT.d}/%.pp: debug/%.tcl debug/instructions.tcl
|
||||||
tclsh $< > $@
|
tclsh $< > $@
|
||||||
|
|
||||||
|
unplug:
|
||||||
|
${PLUG} -u -d token_list '' -d scanner_instructions '' -d parser_rules '' source/eaxhla.l source/eaxhla.y
|
||||||
|
|
||||||
plug: ${OBJECT.d}/token_list.pp ${OBJECT.d}/scanner_instructions.pp ${OBJECT.d}/parser_rules.pp
|
plug: ${OBJECT.d}/token_list.pp ${OBJECT.d}/scanner_instructions.pp ${OBJECT.d}/parser_rules.pp
|
||||||
plug -u -d token_list '' -d scanner_instructions '' -d parser_rules '' source/eaxhla.l source/eaxhla.y
|
${PLUG} -g -e token_list ${OBJECT.d}/token_list.pp source/eaxhla.y
|
||||||
plug -g -e token_list ${OBJECT.d}/token_list.pp source/eaxhla.y
|
${PLUG} -g -e scanner_instructions ${OBJECT.d}/scanner_instructions.pp source/eaxhla.l
|
||||||
plug -g -e scanner_instructions ${OBJECT.d}/scanner_instructions.pp source/eaxhla.l
|
${PLUG} -g -e parser_rules ${OBJECT.d}/parser_rules.pp source/eaxhla.y
|
||||||
plug -g -e parser_rules ${OBJECT.d}/parser_rules.pp source/eaxhla.y
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY: test clean bootstrap
|
.PHONY: test clean bootstrap
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
# DEADLINES
|
|
||||||
|
|
||||||
- EAXHLA Stable By 24/07/26: Waiting.
|
|
@ -1,4 +1 @@
|
|||||||
+ {} is the new artimetric
|
|
||||||
+ [] is the new dereference
|
|
||||||
+ terrible infinit error on ../debug/comment\_as\_space.eax
|
+ terrible infinit error on ../debug/comment\_as\_space.eax
|
||||||
+ arrays
|
|
||||||
|
@ -361,7 +361,7 @@ instruction: INOP { append_instruction_t1(NOP); }
|
|||||||
| ITSUB register register { append_instruction_t6( SUB, $2.size, REG, $2.number, REG, $3.number ); }
|
| ITSUB register register { append_instruction_t6( SUB, $2.size, REG, $2.number, REG, $3.number ); }
|
||||||
| ITXOR register register { append_instruction_t6( XOR, $2.size, REG, $2.number, REG, $3.number ); }
|
| ITXOR register register { append_instruction_t6( XOR, $2.size, REG, $2.number, REG, $3.number ); }
|
||||||
| ITCMP register register { append_instruction_t6( CMP, $2.size, REG, $2.number, REG, $3.number ); }
|
| ITCMP register register { append_instruction_t6( CMP, $2.size, REG, $2.number, REG, $3.number ); }
|
||||||
| ITMOV register immediate { append_instruction_t6( MOV, $2.size, REG, $2.number, IMM, (int)3 ); }
|
| ITMOV register immediate { append_instruction_t6( MOV, $2.size, REG, $2.number, IMM, (int)$3 ); }
|
||||||
|
|
||||||
// #placeholder<parser_rules> END
|
// #placeholder<parser_rules> END
|
||||||
;
|
;
|
||||||
|
@ -11,7 +11,7 @@ proc make_parser_rules {is} {
|
|||||||
}
|
}
|
||||||
"immediate" {
|
"immediate" {
|
||||||
dict set r enum "IMM"
|
dict set r enum "IMM"
|
||||||
dict set r value "(int)$n"
|
dict set r value "(int)$$n"
|
||||||
dict set r size "32"
|
dict set r size "32"
|
||||||
}
|
}
|
||||||
"memory" {
|
"memory" {
|
239
tool/plug
Executable file
239
tool/plug
Executable file
@ -0,0 +1,239 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# "PlacehoLder Un- and Generator"
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
from enum import Enum, auto
|
||||||
|
|
||||||
|
C = {} # ANSI colors
|
||||||
|
|
||||||
|
def has_color():
|
||||||
|
import os
|
||||||
|
return "color" in os.environ.get('TERM')
|
||||||
|
|
||||||
|
def def_colors():
|
||||||
|
global C
|
||||||
|
C = {
|
||||||
|
'b': '\033[34m',
|
||||||
|
'y': '\033[33m',
|
||||||
|
'g': '\033[32m',
|
||||||
|
'r': '\033[31m',
|
||||||
|
'm': '\033[35m',
|
||||||
|
'B': '\033[1m',
|
||||||
|
'R': '\033[7m',
|
||||||
|
'n': '\033[0m',
|
||||||
|
}
|
||||||
|
|
||||||
|
def undef_colors():
|
||||||
|
global C
|
||||||
|
C = {
|
||||||
|
'b': '',
|
||||||
|
'y': '',
|
||||||
|
'g': '',
|
||||||
|
'r': '',
|
||||||
|
'B': '',
|
||||||
|
'n': '',
|
||||||
|
'R': '',
|
||||||
|
'm': '',
|
||||||
|
}
|
||||||
|
undef_colors()
|
||||||
|
|
||||||
|
class Error(Enum):
|
||||||
|
PARAM_MISS = auto()
|
||||||
|
UNK_FLAG = auto()
|
||||||
|
IO = auto()
|
||||||
|
UNK_OPT = auto()
|
||||||
|
UNTERM_DEF = auto()
|
||||||
|
NO_FILES = auto()
|
||||||
|
MULTI_OP = auto()
|
||||||
|
NO_OP = auto()
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print(
|
||||||
|
'''{C[g]}{C[B]}{argv0}{C[n]} {C[B]}{C[y]}({C[b]}-g{C[y]}|{C[b]}-u{C[y]}) {C[B]}{C[y]}({C[b]}<option>{C[y]}|{C[b]}<file>{C[y]})+{C[n]}
|
||||||
|
{C[y]}Options:{C[n]}
|
||||||
|
{C[g]}{C[B]}-h{C[n]} {C[b]}{C[B]}{C[n]} : print help and exit
|
||||||
|
{C[g]}{C[B]}--color{C[n]} {C[B]}{C[b]}never{C[y]}|{C[b]}auto{C[y]}|{C[b]}always{C[n]} : set output coloring option; default: auto
|
||||||
|
{C[g]}{C[B]}-d{C[n]} {C[b]}{C[B]}<name> <value>{C[n]} : define placeholder on the cli
|
||||||
|
{C[g]}{C[B]}-e{C[n]} {C[b]}{C[B]}<name> <file>{C[n]} : define placeholder as the contents of <file>
|
||||||
|
{C[g]}{C[B]}-u{C[n]} : ungenerate placeholders (ie. collapse)
|
||||||
|
{C[g]}{C[B]}-g{C[n]} : generate placeholders (ie. expand)
|
||||||
|
Every argument not starting with '-' is considered a file.
|
||||||
|
If multiple files are specified, actions apply to all of them.
|
||||||
|
Undefine placeholders are left intact.
|
||||||
|
|
||||||
|
{C[y]}{C[B]}Placeholder syntax:{C[n]}
|
||||||
|
{C[y]}#placeholder<{C[n]}<name>{C[y]}> COLLAPSED{C[n]}
|
||||||
|
{C[m]}{C[R]}NOTE:{C[n]} text located on the same line and before the placeholder is preserved.
|
||||||
|
This allows you to comment it out while embedding.
|
||||||
|
{C[y]}Builtins:{C[n]}
|
||||||
|
Builtin placeholder names start with '@', these names are reserved.
|
||||||
|
This Plug version defines the following builtins:
|
||||||
|
{C[b]}@gnu-tofile-*{C[n]}
|
||||||
|
|
||||||
|
{C[y]}{C[B]}Example:{C[n]}
|
||||||
|
// XXX REDO THIS WHOLE SECTION
|
||||||
|
'''.format(**globals(), argv0 = sys.argv[0]), end='')
|
||||||
|
|
||||||
|
destination_files = []
|
||||||
|
operation = ""
|
||||||
|
|
||||||
|
placeholders = {}
|
||||||
|
|
||||||
|
placeholder = '#placeholder<{0}>'
|
||||||
|
placeholder_collapsed = placeholder + ' COLLAPSED'
|
||||||
|
placeholder_expanded_beginning = placeholder + ' BEGIN'
|
||||||
|
placeholder_expanded_ending = placeholder + ' END'
|
||||||
|
del placeholder
|
||||||
|
|
||||||
|
re_placeholder_collapsed = re.compile('''^(.*){0}.*'''.format(placeholder_collapsed.format('''([a-zA-Z0-9_@-]+)''')), re.M)
|
||||||
|
re_placeholder_expanded_beginning = re.compile('''^(.*){0}.*'''.format(placeholder_expanded_beginning.format('''([a-zA-Z0-9_@-]+)''')), re.M)
|
||||||
|
re_placeholder_expanded_ending = re.compile('''^.*{0}.*'''.format(placeholder_expanded_ending.format('''([a-zA-Z0-9_@-]+)''')), re.M)
|
||||||
|
|
||||||
|
|
||||||
|
builtins = [
|
||||||
|
('''@gnu-tofile-(.*)''',
|
||||||
|
'''payload_data=$(sed -n '/#placeholder<payload> START$/,/#placeholder<payload> END$/p' "$(realpath $0)")
|
||||||
|
payload_data=$(echo "$payload_data" | grep -vE '#placeholder<payload> (START|END)')
|
||||||
|
[ -z "$PAYLOADOUT" ] && PAYLOADOUT="out"
|
||||||
|
echo "$payload_data" > "$PAYLOADOUT"'''
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
def builtin_lookup(phl : str) -> str:
|
||||||
|
for i in builtins:
|
||||||
|
regex, value = i
|
||||||
|
m = re.compile(regex).match(phl)
|
||||||
|
if m:
|
||||||
|
value = value.format(m.groups()[1:])
|
||||||
|
return value
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def gen(s : str, phls : [str]) -> str:
|
||||||
|
for phl in phls:
|
||||||
|
buf = ''
|
||||||
|
l = 0
|
||||||
|
for m in re_placeholder_collapsed.finditer(s):
|
||||||
|
if (m.group(2) != phl): continue
|
||||||
|
buf += s[l : m.start(0)]
|
||||||
|
buf += m.group(1) + placeholder_expanded_beginning.format(phl) + '\n'
|
||||||
|
buf += builtin_lookup(phl) if phl[0] == '@' else placeholders[phl]
|
||||||
|
buf += '\n' + m.group(1) + placeholder_expanded_ending.format(phl)
|
||||||
|
l = m.end(0)
|
||||||
|
buf += s[l:]
|
||||||
|
s = buf
|
||||||
|
|
||||||
|
return s
|
||||||
|
|
||||||
|
def ungen(s : str, phls : [str]) -> str:
|
||||||
|
for phl in phls:
|
||||||
|
buf = ''
|
||||||
|
l = 0
|
||||||
|
for m in re_placeholder_expanded_beginning.finditer(s):
|
||||||
|
if(m.group(2) != phl): continue
|
||||||
|
buf += s[l : m.start(0)]
|
||||||
|
buf += m.group(1) + placeholder_collapsed.format(phl)
|
||||||
|
l = m.end(0)
|
||||||
|
for me in re_placeholder_expanded_ending.finditer(s[m.end(0):]):
|
||||||
|
if(me.group(1) != phl): continue
|
||||||
|
l = m.end(0) + me.end(0)
|
||||||
|
break
|
||||||
|
buf += s[l:]
|
||||||
|
s = buf
|
||||||
|
return s
|
||||||
|
|
||||||
|
def error_and_quit(e : int, argv : [str]) -> None:
|
||||||
|
message = {
|
||||||
|
Error.PARAM_MISS : "Missing parameter to flag '{0}'.",
|
||||||
|
Error.UNK_FLAG : "Unrecognized flag '{0}'.",
|
||||||
|
Error.UNK_OPT : "Unknown option passed to {0}: '{1}'.",
|
||||||
|
Error.IO : "I/O error encountered while interacting with '{0}'.",
|
||||||
|
Error.UNTERM_DEF : "Unterminated definition ({0}).",
|
||||||
|
Error.NO_FILES : "Flags were specified, but no files.",
|
||||||
|
Error.MULTI_OP : "Multiple operations specified, '-g'/'-u' are mutually exclive.",
|
||||||
|
Error.NO_OP : "No operation operation specified. Either '-g' or '-u' is required.",
|
||||||
|
}
|
||||||
|
formatted_message = message[e].format(*argv, **globals())
|
||||||
|
print("{C[r]}{msg}{C[n]}".format(**globals(), msg=formatted_message))
|
||||||
|
exit(e.value)
|
||||||
|
|
||||||
|
# We need this function because getopt does not support a single flag taking 2 arguments
|
||||||
|
def parse_args(argv : [str]) -> None:
|
||||||
|
global destination_files, operation
|
||||||
|
def get_param(argv : [str], i : int) -> str:
|
||||||
|
try: param = argv[i]
|
||||||
|
except: error_and_quit(Error.PARAM_MISS, [argv[i-1]])
|
||||||
|
return param
|
||||||
|
|
||||||
|
for arg in argv:
|
||||||
|
if arg == '-h' or arg == '--help':
|
||||||
|
usage()
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
i = 0
|
||||||
|
while i < len(argv):
|
||||||
|
# 0 parama opt
|
||||||
|
if argv[i] == '-u' or argv[i] == '-g':
|
||||||
|
if operation != '': error_and_quit(Error.MULTI_OP, [])
|
||||||
|
operation = argv[i][1]
|
||||||
|
i = i + 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 1 param opt
|
||||||
|
if argv[i-1] == '--color':
|
||||||
|
p = get_param(argv, i)
|
||||||
|
if p == 'always': def_colors()
|
||||||
|
elif p == 'auto' and has_color: def_colors()
|
||||||
|
elif p == 'never': undef_colors()
|
||||||
|
else: error_and_quit(Error.UNK_OPT, ['--color', p])
|
||||||
|
i = i + 2
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 2 param opt
|
||||||
|
if argv[i] == '-d':
|
||||||
|
placeholders[argv[i+1]] = argv[i+2]
|
||||||
|
i = i + 3
|
||||||
|
continue
|
||||||
|
|
||||||
|
if argv[i] == '-e':
|
||||||
|
with open(argv[i+2], "r") as f: placeholders[argv[i+1]] = f.read()
|
||||||
|
i = i + 3
|
||||||
|
continue
|
||||||
|
|
||||||
|
# catch all
|
||||||
|
if argv[i][0] != '-': # file
|
||||||
|
destination_files.append(argv[i])
|
||||||
|
i = i + 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
error_and_quit(Error.UNK_FLAG, [argv[i]])
|
||||||
|
except IndexError: error_and_quit(Error.PARAM_MISS, [argv[i]])
|
||||||
|
except FileNotFoundError as e: error_and_quit(Error.IO, [e.filename])
|
||||||
|
|
||||||
|
def plug(argv : [str]) -> int:
|
||||||
|
global destination_files, operation
|
||||||
|
if has_color: def_colors()
|
||||||
|
|
||||||
|
if len(argv) < 2:
|
||||||
|
usage()
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
parse_args(argv)
|
||||||
|
|
||||||
|
if destination_files == []:
|
||||||
|
error_and_quit(Error.NO_FILES, [])
|
||||||
|
|
||||||
|
if operation == '': error_and_quit(Error.NO_OP, [argv[i-1]])
|
||||||
|
elif operation == 'g': gen_callback = gen
|
||||||
|
elif operation == 'u': gen_callback = ungen
|
||||||
|
|
||||||
|
for df in destination_files:
|
||||||
|
try:
|
||||||
|
with open(df, 'r') as f: s = gen_callback(f.read(), placeholders)
|
||||||
|
with open(df, 'w') as f: f.write(s)
|
||||||
|
except FileNotFoundError: error_and_quit(Error.IO, df)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
raise SystemExit(plug(sys.argv[1:]))
|
Reference in New Issue
Block a user