From 5fa47dc3776e62a2aab4e3c4749029402a8d8f63 Mon Sep 17 00:00:00 2001 From: DiamondNether90 Date: Sat, 18 Oct 2025 19:55:02 +1100 Subject: [PATCH] Start of redesign --- docs/syntax.md | 53 ++--------- src/__pycache__/codegen.cpython-313.pyc | Bin 0 -> 5491 bytes src/__pycache__/error.cpython-313.pyc | Bin 365 -> 403 bytes src/__pycache__/eval.cpython-313.pyc | Bin 1003 -> 141 bytes src/__pycache__/preprocess.cpython-313.pyc | Bin 1541 -> 1042 bytes src/codegen.py | 98 +++++++++++++++++++++ src/error.py | 5 +- src/eval.py | 21 ----- src/main.py | 98 ++------------------- src/preprocess.py | 60 +++++-------- test.bf | 2 +- tests/create.basm | 5 +- 12 files changed, 140 insertions(+), 202 deletions(-) create mode 100644 src/__pycache__/codegen.cpython-313.pyc create mode 100644 src/codegen.py diff --git a/docs/syntax.md b/docs/syntax.md index 85f6cc5..706d64f 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -1,59 +1,16 @@ To create a comment, begin a line with a hash (#) symbol, like python. -## create var *bytes = Value +So far, the supported types are `bool` and `string`. + +## create name type bytes value Creates the variable "var" with a set number of bytes allocated to it, and initialises its value. **IMPORTANT:** The number of bytes cannot be modified later. -Example: `create var *5 = "Hello"` +Example: `create var bool 1 true` ## print var Prints the value of `var` to the console, where `var` is a variable. -Example: `print var` - -## set var = Value - -Changes the value of an already created value. - -Examples: -``` -set var = "World" -set var[0] = "w" -``` - -## input var *bytes = type *ibytes - -Creates a new variable that is `bytes` long, that reads the first `ibytes` of input. - -Example: `input str *5 = string *3` (3 bytes of input, remaining 2 bytes are left blank) - -## if bool - -Runs code if a boolean is true. - -Example: -``` -# If a boolean is true -if bool { - set str = "Hello" -} - -# If second byte of var and third byte of var are equal -if var[1] == var[2] { - set bool = true -} -``` - -## while bool - -Runs code until a boolean is false - -Example: -``` -create bool *1 = true -while bool { - # Loops forever because bool is never false -} -``` \ No newline at end of file +Example: `print var` \ No newline at end of file diff --git a/src/__pycache__/codegen.cpython-313.pyc b/src/__pycache__/codegen.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6d54e25498362883000b528c7de770aa7830330 GIT binary patch literal 5491 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 delta 169 zcmbQt{Fce?GcPX}0}z}M_>d6@q#uJgFu(+5d=>&SrZNOG#4wmJ1v5%9WU&-6rZZ_W zPpp+^G?_S8ktdoNrpJ_F;x+{#rdzB9MVWaew^#~GGfOlXi`X#xnpFOfHRr@ z{nKer8ls?uQv4sK|M!{=uxaCbQXp*5p75ru+n#8Z3`)Li zsf0}y6KIUEfq4Rp zX_KXjCoqHb(`43@^_ed3zzu{QR13P{m~*|h;L3x}jp~vcjXTe4rYjFQGtKb1gK*qg zY@`~a&ECs<;pEq_w0X}BMx1yp;VQ#b!Hvt?iLFFE_2GPV-j(9c#Vw(Z>cbz!FVbj3 z-j_yQN!|`^h3fP5Y=f)c-WrV(64uTc3aoP$Dv2yui&uF<&J@e#r2_B)oKBydS8bcawE5UcSqm3@RNBvTE78bqS=Q4 diff --git a/src/__pycache__/preprocess.cpython-313.pyc b/src/__pycache__/preprocess.cpython-313.pyc index 2f170a75f2f48c3ef93011c99652ed5e39482c29..6ba5c17da896216b894c1db72724e4b640bd6178 100644 GIT binary patch literal 1042 zcmb7C%}*0i5TCanWeff80u@kdL7_3Qi5~|MOoY^k0Zdq$a3Gr6ZeX?DHoGN?a;Wjr z!exON*Th4;>7PR&;rTpz@>W7L-gI^a@!&yc^WMz--f!m3%)X;wupLlB_ggDE5AfM_ zPQ-U?9Hr2B1u86oN|xLYL`2+mRZzJecqEwIGM^ThkS`ZB<}RF*ubocw9mj;&8_XFvP5=@?(ntxp4sRgi{6gE(OM(AgTaliAp?MM*H}5 z{?FTx?MjwhJ4Tbp`x`@nQ-)j9>=eLk1|x;xUnwBRAu@-EsES@y*oo>hgjuW*v9_^g z)ci;r!0(7ofW^*{AofC#A$d`LmvzFp1O`9*6!Shq^dIZ@s@n$WfaGcaUH=zSI~-z`&5)kGp8H3EK4gr zEUqb*nO7>NRx!(Y&9X)-Ypng$HDj2{{hii#+-g8$axFtsgH5@1hj#Vi*4ibi5}k+y|x?!~%o?zNqv@m^=jnYSnE677iB?j2$8Fqh^TZ&ghu6m?YY zU_O8uM`cEFW72r3Tv#n?H_dKzy_qG^Xz_%Q7I%)ww%P(z&O&prX}wFodGOVBy$nAA DB}L=q literal 1541 zcmbVM-ESL35TCsdf5n$LjT2jqi`*upG0?i9RDu*Lpbbq5jwP;1&^d!b3zBdGbT|q+IVW{36m)5o=<=$x3jFdLimn`m&lD=J ztC>Kt=PowH7Sx%+tp%${WW*0gI{I}&z%LR<<+TE9265xL0qEjzo52-t>F+{QWhNi ztd4?9)nzBJ0%NdvAHWH&1a)P;0AON6aBEHjK%F|!$*4=9PMt+)PA1kamln4I;uiN% z`qo#$Q3{DusB=i}?28r?%Q~>UEBu4=i((J){S?NIFNgbbAJKfRclSm&%09-5{PByK z^U#n!<=G1=9Pf|Cx!%3>pdP#ixvvFoWFB!#Jf|IT9uhg>8LJUk2@ImZ4lSG%c}e*} zh8S;@-xvNrb$xO_0}MeL{!e@>@-$?$WdezVBIt$zG#cG95Di=TOjW4m?5PIW) z2@);IBG0FY@(S>YaQ{Vy<8mb4Sn%T$jmv)OrN*K^F^MdZYApGQ$;Q&}+UOSXhoVho z_boqpY-h>WhMQBn1wWbES$eEZ{1%P%HIq}fZ*DF6(b4TII}4As@t))lk2KG2Z|u(< z$amg+piLi=L;YUpS8dK8i8U|oe&NT)_aaTzkH){xZ|Cn`I!HWBop}_U!;rQX{E6h& zW$~7PxwYZPMw|MNAwPAz8UAx5>Bka#(Y@f4F2)mXY;ofc;iuIok7-? h2_erUnan%|WbMdF5^w5lz-|BP!StO^{^6p)`48!#Qk4Jz diff --git a/src/codegen.py b/src/codegen.py new file mode 100644 index 0000000..6e8db5a --- /dev/null +++ b/src/codegen.py @@ -0,0 +1,98 @@ +from error import error +import math as m + +class Variable: + def __init__(self, name: str, bytes: int, startByte: int, type: int): + self.name: str = name + self.bytes: int = bytes + self.startByte: int = startByte + self.type: int = type + def __repr__(self) -> str: + return f"[{self.name}, {self.bytes}, {self.startByte}, {self.type}]" + +variables: list[Variable] = [] +bytesum: int = 0 + +types = { + "bool": 0, + "string": 1, + "int": 2, +} + +bool = { + "true": 1, + "false": 0, +} + +def generateCode(line: list[str], offset: int) -> str: + try: + bytesum = variables[-1].startByte + variables[-1].bytes + except IndexError: + bytesum = 0 + keyword = line[0] + if keyword == 'create': + if len(line) != 5: + error(f"Create command requires 4 arguments (got {len(line)-1})") + name = line[1] + try: + type = types[line[2]] + except KeyError: + error(f"Invalid type: {line[2]}") + quit() + bytes = int(line[3]) + value = line[4] + + if type == 0: + variables.append(Variable(name, bytes, bytesum, type)) + if (value == 'true'): + return '>' * offset + '[>]' + '>' * (bytesum + 1) + '+' + '<' * (bytesum + 1) + '<[<]' + '<' * (offset - 1) + elif (value == 'false'): + return '' + else: + error(f'Invalid bool: {value}') + elif type == 1: + variables.append(Variable(name, bytes, bytesum, type)) + returnval: str = '>' * offset + '[>]' + '>' * (bytesum + 1) + for i in range(bytes): + returnval += '+' * ord(value[i]) + '>' + returnval += '<' * (bytes+bytesum+2) + '[<]' + '<' * (offset - 1) + return returnval + elif type == 2: + # I hate integers + error('Integers are not yet implemented') + else: + error(f"Type {type} not yet implemented") + + error() + quit() + elif keyword == 'print': + if len(line) != 2: + error(f"Print command requires 1 argument (got {len(line)-1})") + + # Find value of variable + var: Variable | str = '' + for v in variables: + if v.name == line[1]: + var = v + + if var == '': + error(f'Could not find variable {line[1]}') + quit() + + print(var.startByte) + if var.type == 0: + # Create copy + returnval = '>' * offset + '[>]' + '>' * (var.startByte + 1) + '[' + '<' * (var.startByte+2) + '[<]<+<+>>>' + '[>]>' + '>' * var.startByte + '-]' + '<' * (var.startByte + 2) + '[<]<' + '[>>[>]' + '>' * (var.startByte + 1) + '+' + '<' * (var.startByte + 2) + '[<]<-]' + # If true + returnval += '+<[>-<' + '+' * 115 + '.--.+++.----------------.[-]' + ']' + # else false + returnval += '>[' + '+' * 101 + '.-----.+++++++++++.+++++++.--------------.[-]' + ']<<<' + return returnval + elif var.type == 1: + return '>' * offset + '[>]' + '>' * (var.startByte + 1) + '.>' * var.bytes + '<' * (var.startByte+var.bytes+2) + '[<]' + '<' * (offset - 1) + else: + error('Type not yet supported') + quit() + else: + error(f"Invalid token: {keyword}") + quit() \ No newline at end of file diff --git a/src/error.py b/src/error.py index bc95f7d..4a0f3df 100644 --- a/src/error.py +++ b/src/error.py @@ -1,3 +1,2 @@ -def error(message: str): - print(f"\033[91mError: \033[0m{message}") - quit() \ No newline at end of file +def error(message: str = "This is a bugged error message. Please report this issue."): + exit(f"\033[91mError: \033[0m{message}") \ No newline at end of file diff --git a/src/eval.py b/src/eval.py index bc77a2f..e69de29 100644 --- a/src/eval.py +++ b/src/eval.py @@ -1,21 +0,0 @@ -from error import error -def eval(type: int, arg: str) -> list[str | int]: - if (type == 0): - if (arg == 'true'): - return ['true'] - elif (arg == 'false'): - return ['false'] - else: - error(f'Invalid bool: {arg}') - quit() - elif type == 1: - rval: list[str | int] = [] - for i in arg.split('+'): - if (i[0] == i[-1] == '\"'): - rval.append(i[1:-1]) - else: - error(f'Invalid token: {arg}') - return rval - else: - error(f'\'{type}\' type not yet implemented') - quit() \ No newline at end of file diff --git a/src/main.py b/src/main.py index ef28100..0d06c72 100644 --- a/src/main.py +++ b/src/main.py @@ -2,8 +2,8 @@ # Note: cells in bf are | 0 | inputs | 0 | variables | from sys import argv from preprocess import preprocess -from eval import eval from error import error +from codegen import generateCode if (len(argv) < 3): print(f"Usage: python {argv[0]} file.basm file.bf") @@ -28,38 +28,8 @@ except IOError: # Pre-processing of the basm file, from preprocess.py code = preprocess(content) -# Variables and references - -class Reference: - def __init__(self, name: str, value: list[str], type: str): - self.name : str = name - self.value : list[str] = value - self.type : str = type - -class Variable: - def __init__(self, name: str, bytes: int, startByte: int, type: int): - self.name: str = name - self.bytes: int = bytes - self.startByte: int = startByte - self.type: int = type - def __repr__(self) -> str: - return f"[{self.name}, {self.bytes}, {self.startByte}, {self.type}]" - -bfcode: str = '>,[>,]<[<]' -variables: list[Variable | Reference] = [] -bytesum: int = 0 - -types = { - "bool": 0, - "str": 1, - "int": 2, - "ref": 3, -} - -bool = { - "false": 0, - "true": 1 -} +offset: int = 5 +bfcode: str = '>' * offset + ',[>,]<[<]' + '<' * (offset-1) def find(str: str, char: str): if (char in str): @@ -67,61 +37,9 @@ def find(str: str, char: str): else: return len(str) -# Main loop +print(code) for line in code: - keyword: str = line.keyword - argument: str = line.argument - if (keyword == ''): - pass - elif (keyword[-1] == '='): - keyword = keyword[:-1] - try: - bytes: int = int(keyword[find(keyword, '*')+1:]) - except: - bytes = 0 - keyword = keyword[:find(keyword, '*')] - - vartype: int - if ':' in keyword: - try: - vartype = types[keyword[keyword.find(':')+1:]] - keyword = keyword[:keyword.find(':')] - except KeyError: - error(f"Cannot find type {keyword[keyword.find(':')+1:]}") - else: - vartype = 3 - - if (keyword in (var.name for var in variables)): - print("Double up?") - else: - # Create new variables - bfcode += ">[>]>" + '>' * bytesum - if (vartype == 0): - # Booleans - if (bytes == 0): - bytes = 1 - variables.append(Variable(keyword, int(bytes), bytesum, 0)) - bfcode += '+' * bool[eval(0, argument)[0]] + '<' * bytesum + '<<[<]' - bytesum += bytes - elif (vartype == 1): - # Strings - if (bytes == 0): - error("None/Invalid Byte Declaration") - variables.append(Variable(keyword, bytes, bytesum, 1)) - print(bytes) - bytesum += bytes - value: list[str] = eval(1, argument) - for a in value: - print(a) - if (type(a) == str): - for b in a: - bfcode += '+' * ord(b) + '>' - else: - error(f"Invalid token: {a}") - bfcode += '<' * bytesum + '<<[<]' - - else: - error(f"Invalid token: {keyword}") - -print(bfcode) -print(variables[0]) \ No newline at end of file + bfcode += generateCode(line, offset) + +with open(argv[2], 'w') as f: + print(f"{f.write(bfcode)} characters successfully compiled!") \ No newline at end of file diff --git a/src/preprocess.py b/src/preprocess.py index 81b6958..2c3d1e4 100644 --- a/src/preprocess.py +++ b/src/preprocess.py @@ -1,45 +1,31 @@ -class Line: - def __init__(self, keyword: str, argument: str): - self.keyword: str = keyword - self.argument: str = argument - -def preprocess(code: str) -> list[Line]: - token : str = "" - keyword : str = "" - tokenise : list[Line] = [] +def preprocess(code: str) -> list[list[str]]: + token : str = '' + tokenise : list[list[str]] = [[]] isString : bool = False - isComment : bool = False - isKeyword : bool = True + isComment : bool = False for i in code: - if i == "\n": + if i == '\n': isComment = False - elif i == "#": - isComment = True + if tokenise[-1] != []: + if token != '': + tokenise[-1].append(token) + tokenise.append([]) + token = '' elif isComment: pass - elif i == '"': - isString = not(isString) + elif i == '#': + isComment = True + elif (i != ' ') | isString: token += i - elif isString: - token += i - elif (i == ';') | (i == '{') | (i == '}'): - if i != ';': - token += i - tokenise.append(Line(keyword, token)) + if (i == '\"'): + isString = not(isString) + else: + tokenise[-1].append(token) token = '' - keyword = '' - isKeyword = True - elif (i != ' '): - if (i == '('): - isKeyword = False - - if isKeyword: - keyword += i - else: - token += i - - if (i == '='): - isKeyword = False - - tokenise.append(Line(keyword, token)) + + if token != '': + tokenise[-1].append(token) + token = '' + if tokenise[-1] == []: + tokenise = tokenise[:-1] return tokenise \ No newline at end of file diff --git a/test.bf b/test.bf index e0a8381..c7f6fa0 100644 --- a/test.bf +++ b/test.bf @@ -1 +1 @@ -++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. \ No newline at end of file +>>>>>,[>,]<[<]<<<<>>>>>[>]>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++><<<<<<<[<]<<<<>>>>>[>]>>>>>>+<<<<<<<[<]<<<<>>>>>[>]>>>>>>[<<<<<<<[<]<+<+>>>[>]>>>>>>-]<<<<<<<[<]<[>>[>]>>>>>>+<<<<<<<[<]<-]+<[>-<+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.--.+++.----------------.[-]]>[+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.-----.+++++++++++.+++++++.--------------.[-]]<<< \ No newline at end of file diff --git a/tests/create.basm b/tests/create.basm index 7edf1d6..656dfea 100644 --- a/tests/create.basm +++ b/tests/create.basm @@ -1,2 +1,3 @@ -var: str *7 = "Hello"; -var2: str *5 = "World"; \ No newline at end of file +create str string 5 Hello +create var bool 1 true +print var \ No newline at end of file