Create variables
This commit is contained in:
		
							
								
								
									
										196
									
								
								src/codegen.py
									
									
									
									
									
								
							
							
						
						
									
										196
									
								
								src/codegen.py
									
									
									
									
									
								
							@@ -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()
 | 
			
		||||
		Reference in New Issue
	
	Block a user