Generating meta data

This commit is contained in:
Krzosa Karol
2022-09-29 19:14:42 +02:00
parent 256eaf8640
commit 3601e83032
5 changed files with 248 additions and 78 deletions

1
.gitignore vendored
View File

@@ -8,3 +8,4 @@
*.c
backup*
__pycache__

View File

@@ -32,29 +32,45 @@ lex_init(Allocator *token_string_arena, Allocator *map_allocator, Lexer *l){
intern_flag = l->intern("flag"_s);
intern_it = l->intern("it"_s);
op_add = l->intern("+"_s);
/*#
import meta
for i in meta.token_simple_expr:
if i[1] != "SPECIAL":
print("op_" + meta.pascal_to_snake(i[0]) + f' = l->intern("{i[1]}"_s);')
first = "op_" + meta.pascal_to_snake(meta.token_simple_expr[0][0])
last = "op_" + meta.pascal_to_snake(meta.token_simple_expr[-1][0])
print(f"l->first_op = {first}")
print(f"l->last_op = {last}")
*/
op_mul = l->intern("*"_s);
op_div = l->intern("/"_s);
op_mod = l->intern("%"_s);
op_left_shift = l->intern("<<"_s);
op_right_shift = l->intern(">>"_s);
op_add = l->intern("+"_s);
op_sub = l->intern("-"_s);
op_and = l->intern("&&"_s);
op_bitand = l->intern("&"_s);
op_or = l->intern("||"_s);
op_bitor = l->intern("|"_s);
op_xor = l->intern("^"_s);
op_equals = l->intern("=="_s);
op_not_equals = l->intern("!="_s);
op_lesser_then_or_equal = l->intern("<="_s);
op_greater_then_or_equal = l->intern(">="_s);
op_lesser_then = l->intern("<"_s);
op_greater_then = l->intern(">"_s);
op_left_shift = l->intern("<<"_s);
op_right_shift = l->intern(">>"_s);
op_not = l->intern("!"_s);
op_not_equals = l->intern("!="_s);
op_bit_and = l->intern("&"_s);
op_bit_or = l->intern("|"_s);
op_bit_xor = l->intern("^"_s);
op_and = l->intern("&&"_s);
op_or = l->intern("||"_s);
op_neg = l->intern("~"_s);
op_not = l->intern("!"_s);
op_decrement = l->intern("--"_s);
op_increment = l->intern("++"_s);
l->first_op = op_add;
l->last_op = op_increment;
op_post_decrement = l->intern("--"_s);
op_post_increment = l->intern("++"_s);
l->first_op = op_mul
l->last_op = op_post_increment
/*END*/
}
function void

View File

@@ -7,57 +7,61 @@ struct Ast_Type;
struct Ast;
struct Ast_Expr;
enum Token_Kind{
TK_End,
TK_Mul,
TK_Div,
TK_Mod,
TK_LeftShift,
TK_RightShift,
TK_FirstMul = TK_Mul,
TK_LastMul = TK_RightShift,
TK_Add,
TK_Sub,
TK_FirstAdd = TK_Add,
TK_LastAdd = TK_Sub,
TK_Equals,
TK_LesserThenOrEqual,
TK_GreaterThenOrEqual,
TK_LesserThen,
TK_GreaterThen,
TK_NotEquals,
TK_FirstCompare = TK_Equals,
TK_LastCompare = TK_NotEquals,
TK_BitAnd,
TK_BitOr,
TK_BitXor,
TK_And,
TK_Or,
TK_FirstLogical = TK_BitAnd,
TK_LastLogical = TK_Or,
TK_Neg,
TK_Not,
TK_Assign,
TK_ColonAssign,
TK_DivAssign,
TK_MulAssign,
TK_ModAssign,
TK_SubAssign,
TK_AddAssign,
TK_AndAssign,
TK_OrAssign,
TK_XorAssign,
TK_LeftShiftAssign,
TK_RightShiftAssign,
TK_FirstAssign = TK_Assign,
TK_LastAssign = TK_RightShiftAssign,
/*#
import meta
for i in meta.token_kinds:
print(" " + i[0] + ",")
*/
Mul,
Div,
Mod,
LeftShift,
RightShift,
FirstMul = TK_Mul,
LastMul = TK_RightShift,
Add,
Sub,
FirstAdd = TK_Add,
LastAdd = TK_Sub,
Equals,
LesserThenOrEqual,
GreaterThenOrEqual,
LesserThen,
GreaterThen,
NotEquals,
FirstCompare = TK_Equals,
LastCompare = TK_NotEquals,
BitAnd,
BitOr,
BitXor,
And,
Or,
FirstLogical = TK_BitAnd,
LastLogical = TK_Or,
Neg,
Not,
Decrement,
Increment,
PostDecrement,
PostIncrement,
Assign,
ColonAssign,
DivAssign,
MulAssign,
ModAssign,
SubAssign,
AddAssign,
AndAssign,
OrAssign,
XorAssign,
LeftShiftAssign,
RightShiftAssign,
FirstAssign = TK_Assign,
LastAssign = TK_RightShiftAssign,
TK_OpenParen,
TK_CloseParen,
TK_OpenBrace,
@@ -71,17 +75,10 @@ enum Token_Kind{
TK_Semicolon,
TK_Dot,
TK_TwoDots,
TK_NewLine,
TK_Colon,
TK_DoubleColon,
TK_At,
TK_Decrement,
TK_Increment,
TK_PostDecrement,
TK_PostIncrement,
TK_Arrow,
TK_ExprSizeof,
TK_DocComment,
@@ -93,6 +90,7 @@ enum Token_Kind{
TK_Float,
TK_Integer,
TK_Keyword,
/*END*/
TK_Pointer = TK_Mul,
TK_Dereference = TK_BitAnd,

92
meta.py Normal file
View File

@@ -0,0 +1,92 @@
import re
snake_case_pattern = re.compile(r'(?<!^)(?=[A-Z])')
def pascal_to_snake(v):
name = snake_case_pattern.sub('_', v).lower()
return name
token_simple_expr = [
["Mul", "*"],
["Div", "/"],
["Mod", "%"],
["LeftShift", "<<"],
["RightShift", ">>"],
["FirstMul = TK_Mul", "SPECIAL"],
["LastMul = TK_RightShift", "SPECIAL"],
["Add", "+"],
["Sub", "-"],
["FirstAdd = TK_Add", "SPECIAL"],
["LastAdd = TK_Sub", "SPECIAL"],
["Equals", "=="],
["LesserThenOrEqual", "<="],
["GreaterThenOrEqual", ">="],
["LesserThen", "<"],
["GreaterThen", ">"],
["NotEquals", "!="],
["FirstCompare = TK_Equals", "SPECIAL"],
["LastCompare = TK_NotEquals", "SPECIAL"],
["BitAnd", "&"],
["BitOr", "|"],
["BitXor", "^"],
["And", "&&"],
["Or", "||"],
["FirstLogical = TK_BitAnd", "SPECIAL"],
["LastLogical = TK_Or", "SPECIAL"],
["Neg", "~"],
["Not", "!"],
["Decrement", "--"],
["Increment", "++"],
["PostDecrement", "--"],
["PostIncrement", "++"],
]
token_assign_expr = [
["Assign", "="],
["ColonAssign", ":="],
["DivAssign", "/="],
["MulAssign", "*="],
["ModAssign", "%="],
["SubAssign", "-="],
["AddAssign", "+="],
["AndAssign", "&="],
["OrAssign", "|="],
["XorAssign", "^="],
["LeftShiftAssign", "<<="],
["RightShiftAssign", ">>="],
["FirstAssign = TK_Assign", "SPECIAL"],
["LastAssign = TK_RightShiftAssign", "SPECIAL"],
]
token_rest = [
["TK_OpenParen", "("],
["TK_CloseParen", ")"],
["TK_OpenBrace", "{"],
["TK_CloseBrace", "}"],
["TK_OpenBracket", "["],
["TK_CloseBracket", "]"],
["TK_Comma", ","],
["TK_Pound", "#"],
["TK_Question", "?"],
["TK_ThreeDots", "..."],
["TK_Semicolon", ";"],
["TK_Dot", "."],
["TK_TwoDots", ".."],
["TK_NewLine", "[NewLine]"],
["TK_Colon", ":"],
["TK_DoubleColon", "::"],
["TK_At", "@"],
["TK_Arrow", "->"],
["TK_ExprSizeof", "[SizeOf]"],
["TK_DocComment", "[///]"],
["TK_Comment", "//"],
["TK_Identifier", "[Ident]"],
["TK_UnicodeLit", "[Unicode]"],
["TK_StringLit", "[String]"],
["TK_Error", "[Error]"],
["TK_Float", "[Float]"],
["TK_Integer", "[Int]"],
["TK_Keyword", "[Keyword]"],
]
token_kinds = token_simple_expr + token_assign_expr + token_rest

63
meta_run.py Normal file
View File

@@ -0,0 +1,63 @@
import subprocess
import sys
import os
files = ["core_compiler.cpp", "core_compiler.h"]
for file_to_modify in files:
fd = open(file_to_modify, "r+")
f = fd.read()
END = "/*END*/"
START = "/*#"
STOP = "*/"
program_counter = 0
valid = True
index = 0
while True:
begin = f.find(START, index)
if begin == -1:
break
index = begin
begin += 3
end = f.find(STOP, index)
if end == -1:
valid = False
print(f"One of the registered comments inside {file_to_modify} doesn't have an end")
break
gen_end = f.find(END, end)
next_block = f.find(START, end)
if next_block != -1 and gen_end > next_block:
gen_end = -1
before = f[:begin]
program = f[begin:end]
if gen_end == -1:
after = f[end+2:]
else:
after = f[gen_end+len(END):]
temp_filename = "_metaprogram" + str(program_counter) + ".py"
if os.path.isfile(temp_filename):
print(temp_filename + " exists, dont want to risk overwriting something important")
valid = False
break
program_counter += 1
with open(temp_filename, "w") as meta_file:
meta_file.write(program)
result = subprocess.run(["py", temp_filename], stdout=subprocess.PIPE)
program_result = result.stdout.decode('utf-8').replace('\r\n', '\n') + END
f = before + program + "*/\n" + program_result + after
os.remove(temp_filename)
index = end
if valid:
fd.seek(0)
fd.write(f)
fd.truncate()
fd.close()