Create variables

This commit is contained in:
2025-10-24 20:32:51 +11:00
parent 176c07151a
commit 9ad3bdbc92
6 changed files with 139 additions and 118 deletions

View File

@@ -1,18 +1,11 @@
## Work in Progress
To create a comment, begin a line with a hash (#) symbol, like python.
So far, the supported types are `bool` and `string`.
Create a string: `string name value bytes`
## create name type bytes value
Create a boolean: `bool name 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.
Create an integer: `int name value`
Example: `create var bool 1 true`
To set a variable to an input byte, use: `create var string 1 i[idx]`.
## print var
Prints the value of `var` to the console, where `var` is a variable.
Example: `print var`
**Note**: A string of dynamic length can be created by setting the bytes to -1.

View File

@@ -2,6 +2,12 @@
BrainAssembly is a language that compiles to Brainfuck. Similar to Assembly languages, it has simple syntax, and is designed to make Brainfuck easier to write code for. Heavily inspired by Ground. Enjoy!
## Features
- Simple syntax: The language is designed to be very simple, and a framework for larger projects. This also means that the syntax is quite easy to learn.
**NOTE:** Due to the current lack of optimisation in the compiled code, we recommend an optimising intepreter such as [this one](https://copy.sh/brainfuck).
To run:
- First clone this repository and install python.
@@ -10,10 +16,21 @@ git clone https://chookspace.com/DiamondNether90/BrainAssembly
```
- Next, run the following command to compile a .basm file to Brainfuck:
```
```bash
python3 src/main.py path/to/file.basm path/to/file.bf
```
(Replace path/to/file.basm with the actual path to your desired .basm file, and replace path/to/file.bf with where you want the compiled file to be created.)
This will create or replace the contents of path/to/file.bf with the compiled BrainAssembly code.
This will create or replace the contents of path/to/file.bf with the compiled BrainAssembly code.
## Test the compiler with our in-built test programs!
You can access our test programs in the test folder.
Example:
```bash
python src/main.py tests/create.basm test.bf
```
This will create a Brainfuck file named test.bf that contains the compiled code of our test programs.

View File

@@ -2,115 +2,121 @@ from error import error
import math as m
class Variable:
def __init__(self, name: str, bytes: int, startByte: int, type: int):
def __init__(self, name: str, bytes: 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}]"
return f"[{self.name}, {self.bytes}, {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:
if value[0] == value[-1] == '"':
value = value[1:-1]
variables.append(Variable(name, bytes, bytesum, type))
returnval = '>' * offset + '[>]' + '>' * (bytesum + 1)
for i in range(bytes):
try:
returnval += '+' * ord(value[i]) + '>'
except IndexError:
returnval += '>'
returnval += '<' * (bytes+bytesum+2) + '[<]' + '<' * (offset - 1)
return returnval
elif (value[:2] == 'i[') & (value[-1] == ']'):
try:
validx: int = int(value[2:-1])
except ValueError:
error(f'Invalid input index: {value[2:-1]}')
quit()
variables.append(Variable(name, bytes, bytesum, type))
returnval = '>' * (offset + validx)
returnval += '[[>]' + '>' * (bytesum+1) + '+' + '<' * (bytesum+2) + '[<]<+' + '>' * (validx+2) + '-]'
returnval += '<[<]<[' + '>' * (validx+2) + '+<[<]<-]<<<'
return returnval
else:
error(f"Invalid string: {value}")
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()
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 + '.-----.+++++++++++.+++++++.--------------.[-]' + ']<<<'
if keyword == 'bool':
if len(line) != 3:
error(f'Bool command requires 2 arguments (got {len(line)-1})')
variables.append(Variable(line[1], 1, 0))
if line[2] == 'true':
returnval = '>' * offset + '[>]'
for var in variables[:-1]:
if var.bytes >= 0:
returnval += '>' * (var.bytes+1)
elif var.bytes == -1:
returnval += '>[>]'
else:
error()
returnval += '>+<'
for var in reversed(variables[:-1]):
if var.bytes >= 0:
returnval += '<' * (var.bytes+1)
elif var.bytes == -1:
returnval += '<[<]'
else:
error()
returnval += '<[<]' + '<' * (offset-1)
return returnval
elif var.type == 1:
return '>' * offset + '[>]' + '>' * (var.startByte + 1) + '.>' * var.bytes + '<' * (var.startByte+var.bytes+2) + '[<]' + '<' * (offset - 1)
elif line[2] == 'false':
return ''
else:
error('Type not yet supported')
quit()
else:
error(f"Invalid token: {keyword}")
quit()
error(f"Invalid bool: {line[2]}")
elif keyword == 'string':
if len(line) != 4:
error(f'String command requires 3 arguments (got {len(line)-1})')
try:
variables.append(Variable(line[1], int(line[2]), 1))
except ValueError:
error(f'Unexpected bytes for string: {line[2]}')
returnval = '>' * offset + '[>]'
for var in variables[:-1]:
if var.bytes >= 0:
returnval += '>' * (var.bytes + 1)
elif var.bytes == -1:
returnval += '>[>]'
else:
error('Cannot have negative byte count (excluding -1)')
returnval += '>'
# Normal string
if line[3][0] == line[3][-1] == '"':
line[3] = line[3][1:-1]
if (len(line[3]) > int(line[2])) & (line[2] != '-1'):
line[3] = line[3][:(int(line[2])-len(line[3]))]
for char in line[3]:
returnval += '+' * ord(char) + '>'
else:
error(f'Invalid string: {line[3]}')
# Return to start
for var in reversed(variables):
if var.bytes >= 0:
returnval += '<' * (var.bytes + 1)
elif var.bytes == -1:
returnval += '<[<]'
else:
error()
returnval += '<[<]' + '<' * (offset-1)
return returnval
elif keyword == 'int':
if len(line) != 3:
error(f'Int requires 2 arguments (got {len(line)-1})')
variables.append(Variable(line[1], 4, 2))
returnval: str = '>' * offset + '[>]'
for var in variables[:-1]:
if var.bytes >= 0:
returnval += '>' * (var.bytes+1)
elif var.bytes == -1:
returnval += '>[>]'
else:
error()
returnval += '>'
try:
input: int = int(line[2]) % 4294967296
except ValueError:
error(f'Invalid integer: {line[2]}')
values: list[int] = []
for i in reversed(range(4)):
values.append(m.floor(input/(256**i)))
input -= values[-1] * (256**i)
for num in values:
returnval += '+' * num + '>'
returnval += '<<<<<'
for var in reversed(variables[:-1]):
if var.bytes >= 0:
returnval += '<' * (var.bytes + 1)
elif var.bytes == -1:
returnval += '<[<]'
else:
error()
returnval += '<[<]' + '<' * (offset-1)
return returnval
error()

View File

@@ -1,2 +1,5 @@
def error(message: str = "This is a bugged error message. Please report this issue."):
exit(f"\033[91mError: \033[0m{message}")
exit(f"\033[91mError: \033[0m{message}")
def warn(message: str):
print(f"\033[33mWarning: {message}")

View File

@@ -31,11 +31,7 @@ code = preprocess(content)
offset: int = 5
bfcode: str = '>' * offset + ',[>,]<[<]' + '<' * (offset-1)
def find(str: str, char: str):
if (char in str):
return str.find(char)
else:
return len(str)
open(argv[2], 'w').write('')
for line in code:
bfcode += generateCode(line, offset)

View File

@@ -1,2 +1,8 @@
create i3 string 1 i[3]
print i3
bool var true
bool var2 false
string str1 -1 "Hell"
bool var3 true
int num1 -1736671613
int num2 9182364129
string str2 5 "World!"
bool var4 true