Start of redesign
This commit is contained in:
@@ -1,59 +1,16 @@
|
|||||||
To create a comment, begin a line with a hash (#) symbol, like python.
|
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.
|
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.
|
**IMPORTANT:** The number of bytes cannot be modified later.
|
||||||
|
|
||||||
Example: `create var *5 = "Hello"`
|
Example: `create var bool 1 true`
|
||||||
|
|
||||||
## print var
|
## print var
|
||||||
|
|
||||||
Prints the value of `var` to the console, where `var` is a variable.
|
Prints the value of `var` to the console, where `var` is a variable.
|
||||||
|
|
||||||
Example: `print var`
|
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
|
|
||||||
}
|
|
||||||
```
|
|
||||||
BIN
src/__pycache__/codegen.cpython-313.pyc
Normal file
BIN
src/__pycache__/codegen.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
98
src/codegen.py
Normal file
98
src/codegen.py
Normal file
@@ -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()
|
||||||
@@ -1,3 +1,2 @@
|
|||||||
def error(message: str):
|
def error(message: str = "This is a bugged error message. Please report this issue."):
|
||||||
print(f"\033[91mError: \033[0m{message}")
|
exit(f"\033[91mError: \033[0m{message}")
|
||||||
quit()
|
|
||||||
21
src/eval.py
21
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()
|
|
||||||
98
src/main.py
98
src/main.py
@@ -2,8 +2,8 @@
|
|||||||
# Note: cells in bf are | 0 | inputs | 0 | variables |
|
# Note: cells in bf are | 0 | inputs | 0 | variables |
|
||||||
from sys import argv
|
from sys import argv
|
||||||
from preprocess import preprocess
|
from preprocess import preprocess
|
||||||
from eval import eval
|
|
||||||
from error import error
|
from error import error
|
||||||
|
from codegen import generateCode
|
||||||
|
|
||||||
if (len(argv) < 3):
|
if (len(argv) < 3):
|
||||||
print(f"Usage: python {argv[0]} file.basm file.bf")
|
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
|
# Pre-processing of the basm file, from preprocess.py
|
||||||
code = preprocess(content)
|
code = preprocess(content)
|
||||||
|
|
||||||
# Variables and references
|
offset: int = 5
|
||||||
|
bfcode: str = '>' * offset + ',[>,]<[<]' + '<' * (offset-1)
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
def find(str: str, char: str):
|
def find(str: str, char: str):
|
||||||
if (char in str):
|
if (char in str):
|
||||||
@@ -67,61 +37,9 @@ def find(str: str, char: str):
|
|||||||
else:
|
else:
|
||||||
return len(str)
|
return len(str)
|
||||||
|
|
||||||
# Main loop
|
print(code)
|
||||||
for line in code:
|
for line in code:
|
||||||
keyword: str = line.keyword
|
bfcode += generateCode(line, offset)
|
||||||
argument: str = line.argument
|
|
||||||
if (keyword == ''):
|
with open(argv[2], 'w') as f:
|
||||||
pass
|
print(f"{f.write(bfcode)} characters successfully compiled!")
|
||||||
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])
|
|
||||||
@@ -1,45 +1,31 @@
|
|||||||
class Line:
|
def preprocess(code: str) -> list[list[str]]:
|
||||||
def __init__(self, keyword: str, argument: str):
|
token : str = ''
|
||||||
self.keyword: str = keyword
|
tokenise : list[list[str]] = [[]]
|
||||||
self.argument: str = argument
|
|
||||||
|
|
||||||
def preprocess(code: str) -> list[Line]:
|
|
||||||
token : str = ""
|
|
||||||
keyword : str = ""
|
|
||||||
tokenise : list[Line] = []
|
|
||||||
isString : bool = False
|
isString : bool = False
|
||||||
isComment : bool = False
|
isComment : bool = False
|
||||||
isKeyword : bool = True
|
|
||||||
for i in code:
|
for i in code:
|
||||||
if i == "\n":
|
if i == '\n':
|
||||||
isComment = False
|
isComment = False
|
||||||
elif i == "#":
|
if tokenise[-1] != []:
|
||||||
isComment = True
|
if token != '':
|
||||||
|
tokenise[-1].append(token)
|
||||||
|
tokenise.append([])
|
||||||
|
token = ''
|
||||||
elif isComment:
|
elif isComment:
|
||||||
pass
|
pass
|
||||||
elif i == '"':
|
elif i == '#':
|
||||||
isString = not(isString)
|
isComment = True
|
||||||
|
elif (i != ' ') | isString:
|
||||||
token += i
|
token += i
|
||||||
elif isString:
|
if (i == '\"'):
|
||||||
token += i
|
isString = not(isString)
|
||||||
elif (i == ';') | (i == '{') | (i == '}'):
|
else:
|
||||||
if i != ';':
|
tokenise[-1].append(token)
|
||||||
token += i
|
|
||||||
tokenise.append(Line(keyword, token))
|
|
||||||
token = ''
|
token = ''
|
||||||
keyword = ''
|
|
||||||
isKeyword = True
|
if token != '':
|
||||||
elif (i != ' '):
|
tokenise[-1].append(token)
|
||||||
if (i == '('):
|
token = ''
|
||||||
isKeyword = False
|
if tokenise[-1] == []:
|
||||||
|
tokenise = tokenise[:-1]
|
||||||
if isKeyword:
|
|
||||||
keyword += i
|
|
||||||
else:
|
|
||||||
token += i
|
|
||||||
|
|
||||||
if (i == '='):
|
|
||||||
isKeyword = False
|
|
||||||
|
|
||||||
tokenise.append(Line(keyword, token))
|
|
||||||
return tokenise
|
return tokenise
|
||||||
2
test.bf
2
test.bf
@@ -1 +1 @@
|
|||||||
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
|
>>>>>,[>,]<[<]<<<<>>>>>[>]>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++><<<<<<<[<]<<<<>>>>>[>]>>>>>>+<<<<<<<[<]<<<<>>>>>[>]>>>>>>[<<<<<<<[<]<+<+>>>[>]>>>>>>-]<<<<<<<[<]<[>>[>]>>>>>>+<<<<<<<[<]<-]+<[>-<+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.--.+++.----------------.[-]]>[+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.-----.+++++++++++.+++++++.--------------.[-]]<<<
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
var: str *7 = "Hello";
|
create str string 5 Hello
|
||||||
var2: str *5 = "World";
|
create var bool 1 true
|
||||||
|
print var
|
||||||
Reference in New Issue
Block a user