Compare commits
No commits in common. "a75e290f874f3bdeedd97a0f811dbdcb3f52f9dc" and "7512a392951401abe78fbaa07b18b9b7ed6eaec2" have entirely different histories.
a75e290f87
...
7512a39295
|
|
@ -1,4 +1,4 @@
|
||||||
; Kyler Olsen - Feb 2024
|
; Yeahbut - Feb 2024
|
||||||
; Example 1 - ytd 12-bit Computer
|
; Example 1 - ytd 12-bit Computer
|
||||||
; Fibonacci
|
; Fibonacci
|
||||||
|
|
||||||
|
|
|
||||||
135
examples/test2.s
135
examples/test2.s
|
|
@ -1,135 +0,0 @@
|
||||||
; Kyler Olsen - Mar 2024
|
|
||||||
; Example 2 - ytd 12-bit Computer
|
|
||||||
; Hello World
|
|
||||||
|
|
||||||
ldi :main
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
print:
|
|
||||||
dec SP SP
|
|
||||||
|
|
||||||
; Output current value
|
|
||||||
liu 0x1F
|
|
||||||
lil 0x3F
|
|
||||||
str D0
|
|
||||||
|
|
||||||
; Return
|
|
||||||
inc SP SP
|
|
||||||
pop MP
|
|
||||||
inc PC MP
|
|
||||||
|
|
||||||
main:
|
|
||||||
; Initialize Stack Pointer
|
|
||||||
liu 0x3F
|
|
||||||
lil 0x3F
|
|
||||||
or SP MP ZR
|
|
||||||
|
|
||||||
; 'H' (0x48)
|
|
||||||
liu 0x1
|
|
||||||
lil 0x08
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; 'e' (0x65)
|
|
||||||
liu 0x1
|
|
||||||
lil 0x25
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; 'l' (0x6c)
|
|
||||||
liu 0x1
|
|
||||||
lil 0x2c
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; 'l' (0x6c)
|
|
||||||
liu 0x1
|
|
||||||
lil 0x2c
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; 'o' (0x6f)
|
|
||||||
liu 0x1
|
|
||||||
lil 0x2f
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; ',' (0x2c)
|
|
||||||
ldi 0x2c
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; ' ' (0x20)
|
|
||||||
ldi 0x20
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; 'W' (0x57)
|
|
||||||
liu 0x1
|
|
||||||
lil 0x17
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; 'o' (0x6f)
|
|
||||||
liu 0x1
|
|
||||||
lil 0x2f
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; 'r' (0x72)
|
|
||||||
liu 0x1
|
|
||||||
lil 0x32
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; 'l' (0x6c)
|
|
||||||
liu 0x1
|
|
||||||
lil 0x2c
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; 'd' (0x64)
|
|
||||||
liu 0x1
|
|
||||||
lil 0x24
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; '!' (0x21)
|
|
||||||
ldi 0x21
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
; '\n' (0xa)
|
|
||||||
ldi 0xa
|
|
||||||
or D0 MP ZR
|
|
||||||
ldi :print
|
|
||||||
psh PC
|
|
||||||
or PC MP ZR
|
|
||||||
|
|
||||||
hlt
|
|
||||||
|
|
@ -22,7 +22,6 @@ fn test_func(arg1: int, arg2: unsigned = 10) -> fixed {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_func2() -> Point {
|
fn test_func2() -> Point {
|
||||||
let test: float;
|
|
||||||
Point.points;
|
Point.points;
|
||||||
test++;
|
test++;
|
||||||
test--;
|
test--;
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,6 @@ class FileInfo:
|
||||||
f"('{self._filename}',{self._line},{self._col},{self._length})"
|
f"('{self._filename}',{self._line},{self._col},{self._length})"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return f"Ln {self.line}, Col {self.col} in file {self.filename}"
|
|
||||||
|
|
||||||
def __add__(self, other: "FileInfo") -> "FileInfo":
|
def __add__(self, other: "FileInfo") -> "FileInfo":
|
||||||
filename = self.filename
|
filename = self.filename
|
||||||
line = self.line
|
line = self.line
|
||||||
|
|
@ -72,18 +69,11 @@ class CompilerError(Exception):
|
||||||
|
|
||||||
_compiler_error_type = "Compiler"
|
_compiler_error_type = "Compiler"
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, message: str, file_info: FileInfo):
|
||||||
self,
|
|
||||||
message: str,
|
|
||||||
file_info: FileInfo,
|
|
||||||
file_info_context: FileInfo | None = None,
|
|
||||||
):
|
|
||||||
new_message = message
|
new_message = message
|
||||||
new_message += (
|
new_message += (
|
||||||
f"\nIn file {file_info.filename} at line {file_info.line} "
|
f"\nIn file {file_info.filename} at line {file_info.line} "
|
||||||
)
|
)
|
||||||
if file_info_context is not None and file_info_context.lines:
|
|
||||||
file_info_context = None
|
|
||||||
if file_info.lines:
|
if file_info.lines:
|
||||||
new_message += f"to line {file_info.line + file_info.lines}"
|
new_message += f"to line {file_info.line + file_info.lines}"
|
||||||
with open(file_info.filename, 'r') as file:
|
with open(file_info.filename, 'r') as file:
|
||||||
|
|
@ -94,23 +84,6 @@ class CompilerError(Exception):
|
||||||
new_message += f"col {file_info.col}\n\n"
|
new_message += f"col {file_info.col}\n\n"
|
||||||
with open(file_info.filename, 'r') as file:
|
with open(file_info.filename, 'r') as file:
|
||||||
new_message += file.readlines()[file_info.line-1]
|
new_message += file.readlines()[file_info.line-1]
|
||||||
if file_info_context is not None:
|
|
||||||
context_line = [' '] * max(
|
|
||||||
file_info.col + file_info.length,
|
|
||||||
file_info_context.col +file_info_context.length,
|
|
||||||
)
|
|
||||||
for i in range(
|
|
||||||
file_info_context.col - 1,
|
|
||||||
file_info_context.col + file_info_context.length
|
|
||||||
):
|
|
||||||
context_line[i] = '~'
|
|
||||||
for i in range(
|
|
||||||
file_info.col - 1,
|
|
||||||
file_info.col + file_info.length
|
|
||||||
):
|
|
||||||
context_line[i] = '^'
|
|
||||||
new_message += ''.join(context_line)
|
|
||||||
else:
|
|
||||||
new_message += ' ' * (
|
new_message += ' ' * (
|
||||||
file_info.col - 1) + '^' * file_info.length
|
file_info.col - 1) + '^' * file_info.length
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,13 @@ from .compiler_types import CompilerError, FileInfo
|
||||||
from . import syntactical_analyzer
|
from . import syntactical_analyzer
|
||||||
|
|
||||||
|
|
||||||
|
class SyntaxError(CompilerError):
|
||||||
|
|
||||||
|
_compiler_error_type = "Semantic"
|
||||||
|
|
||||||
|
|
||||||
type SymbolDefinitionTypes = (
|
type SymbolDefinitionTypes = (
|
||||||
InternalDefinition |
|
InternalDefinition |
|
||||||
syntactical_analyzer.FunctionParameter |
|
|
||||||
syntactical_analyzer.LetStatement |
|
syntactical_analyzer.LetStatement |
|
||||||
syntactical_analyzer.ForPreDef |
|
syntactical_analyzer.ForPreDef |
|
||||||
syntactical_analyzer.StructBlock |
|
syntactical_analyzer.StructBlock |
|
||||||
|
|
@ -26,123 +30,6 @@ type SymbolReferenceTypes = (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type Identifier = syntactical_analyzer.Identifier | CompoundIdentifier
|
|
||||||
|
|
||||||
|
|
||||||
type Statement = (
|
|
||||||
syntactical_analyzer.Expression |
|
|
||||||
syntactical_analyzer.LetStatement |
|
|
||||||
syntactical_analyzer.LoopStatements |
|
|
||||||
syntactical_analyzer.NestableCodeBlock |
|
|
||||||
Identifier
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
BaseValues: tuple[type, ...] = (
|
|
||||||
syntactical_analyzer.BuiltInConst,
|
|
||||||
syntactical_analyzer.NumberLiteral,
|
|
||||||
syntactical_analyzer.CharLiteral,
|
|
||||||
syntactical_analyzer.StringLiteral,
|
|
||||||
syntactical_analyzer.Identifier,
|
|
||||||
syntactical_analyzer.FunctionCall,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
NestableCodeBlocks: tuple[type, ...] = (
|
|
||||||
syntactical_analyzer.ForBlock,
|
|
||||||
syntactical_analyzer.WhileBlock,
|
|
||||||
syntactical_analyzer.DoBlock,
|
|
||||||
syntactical_analyzer.IfBlock,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class SyntaxError(CompilerError):
|
|
||||||
|
|
||||||
_compiler_error_type = "Semantic"
|
|
||||||
|
|
||||||
|
|
||||||
class VariableAlreadyDeclared(SyntaxError):
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
new: SymbolDefinitionTypes,
|
|
||||||
existing: SymbolDefinitionTypes,
|
|
||||||
):
|
|
||||||
message = (
|
|
||||||
f"The variable '{new.identifier.content}' was already "
|
|
||||||
f"declared at {str(existing.file_info)}" # type: ignore
|
|
||||||
)
|
|
||||||
super().__init__(message, new.file_info) # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
class UndeclaredVariable(SyntaxError):
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
variable: SymbolDefinitionTypes,
|
|
||||||
):
|
|
||||||
message = (
|
|
||||||
f"The variable '{variable.identifier.content}' is undeclared."
|
|
||||||
)
|
|
||||||
super().__init__(message, variable.file_info) # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidOperand(SyntaxError):
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
operator: (
|
|
||||||
syntactical_analyzer.TernaryExpression |
|
|
||||||
syntactical_analyzer.BinaryExpression |
|
|
||||||
syntactical_analyzer.UnaryExpression
|
|
||||||
),
|
|
||||||
operand: Statement,
|
|
||||||
):
|
|
||||||
message = (
|
|
||||||
f"The operand at '{operand}' is invalid for the "
|
|
||||||
f"operator '{operator.operator.content.value}'."
|
|
||||||
)
|
|
||||||
super().__init__(
|
|
||||||
message,
|
|
||||||
operand.file_info, # type: ignore
|
|
||||||
operator.file_info, # type: ignore
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CompoundIdentifier:
|
|
||||||
|
|
||||||
_owner: Identifier
|
|
||||||
_member: Identifier
|
|
||||||
_file_info: FileInfo
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
owner: Identifier,
|
|
||||||
member: Identifier,
|
|
||||||
file_info: FileInfo,
|
|
||||||
):
|
|
||||||
self._owner = owner
|
|
||||||
self._member = member
|
|
||||||
self._file_info = file_info
|
|
||||||
|
|
||||||
@property
|
|
||||||
def owner(self) -> Identifier: return self._owner
|
|
||||||
|
|
||||||
@property
|
|
||||||
def member(self) -> Identifier: return self._member
|
|
||||||
|
|
||||||
@property
|
|
||||||
def file_info(self) -> FileInfo: return self._file_info
|
|
||||||
|
|
||||||
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
|
||||||
s: str = f"{pre} CompoundIdentifier\n"
|
|
||||||
s += f"{pre_cont}├─ Owner\n"
|
|
||||||
s += self._owner.tree_str(pre_cont + " ├─", pre_cont + " │ ")
|
|
||||||
s += f"{pre_cont}└─ Member\n"
|
|
||||||
s += self._member.tree_str(pre_cont + " └─", pre_cont + " ")
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
class InternalDefinition:
|
class InternalDefinition:
|
||||||
|
|
||||||
_identifier: syntactical_analyzer.Identifier
|
_identifier: syntactical_analyzer.Identifier
|
||||||
|
|
@ -205,11 +92,7 @@ class Symbol:
|
||||||
def symbol_type(self) -> SymbolType: return self._symbol_type
|
def symbol_type(self) -> SymbolType: return self._symbol_type
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def references(self) -> list[SymbolReferenceTypes]:
|
def references(self): return self._references[:]
|
||||||
return self._references[:]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def definition(self) -> SymbolDefinitionTypes: return self._definition
|
|
||||||
|
|
||||||
def add_reference(self, ref: SymbolReferenceTypes):
|
def add_reference(self, ref: SymbolReferenceTypes):
|
||||||
self._references.append(ref)
|
self._references.append(ref)
|
||||||
|
|
@ -340,19 +223,12 @@ class FunctionBlock:
|
||||||
|
|
||||||
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
||||||
s: str = f"{pre} Function: {self._identifier}\n"
|
s: str = f"{pre} Function: {self._identifier}\n"
|
||||||
if (
|
if self._params or self._code or self._return_type is not None:
|
||||||
self._params or
|
s += self._symbol_table.table_str("GLOBAL", "├─", "│ ")
|
||||||
self._code or
|
|
||||||
self._return_type is not None or
|
|
||||||
self._members
|
|
||||||
):
|
|
||||||
s += self._symbol_table.table_str(
|
|
||||||
self.identifier.content, "├─", "│ ")
|
|
||||||
else:
|
else:
|
||||||
s += self._symbol_table.table_str(
|
s += self._symbol_table.table_str("GLOBAL", "└─", " ")
|
||||||
self.identifier.content, "└─", " ")
|
|
||||||
if self._params:
|
if self._params:
|
||||||
if self._code or self._return_type is not None or self._members:
|
if self._code or self._return_type is not None:
|
||||||
s += f"{pre_cont}├─ Parameters\n"
|
s += f"{pre_cont}├─ Parameters\n"
|
||||||
params_pre = f"{pre_cont}│ "
|
params_pre = f"{pre_cont}│ "
|
||||||
else:
|
else:
|
||||||
|
|
@ -362,21 +238,12 @@ class FunctionBlock:
|
||||||
s += param.tree_str(params_pre + "├─", params_pre + "│ ")
|
s += param.tree_str(params_pre + "├─", params_pre + "│ ")
|
||||||
s += self._params[-1].tree_str(params_pre + "└─", params_pre + " ")
|
s += self._params[-1].tree_str(params_pre + "└─", params_pre + " ")
|
||||||
if self._return_type is not None:
|
if self._return_type is not None:
|
||||||
if self._code or self._members:
|
if self._code:
|
||||||
s += f"{pre_cont}├─ Return Type: "
|
s += f"{pre_cont}├─ Return Type: "
|
||||||
else:
|
else:
|
||||||
s += f"{pre_cont}└─ Return Type: "
|
s += f"{pre_cont}└─ Return Type: "
|
||||||
if self._return_type_pointer: s+= "@"
|
if self._return_type_pointer: s+= "@"
|
||||||
s += f"{self._return_type}\n"
|
s += f"{self._return_type}\n"
|
||||||
if self._members:
|
|
||||||
if self._code:
|
|
||||||
s += f"{pre_cont}├─ Members: "
|
|
||||||
else:
|
|
||||||
s += f"{pre_cont}└─ Members: "
|
|
||||||
for code in self._members[:-1]:
|
|
||||||
s += code.tree_str(pre_cont + " ├─", pre_cont + " │ ")
|
|
||||||
s += self._members[-1].tree_str(
|
|
||||||
pre_cont + " └─", pre_cont + " ")
|
|
||||||
if self._code:
|
if self._code:
|
||||||
s += f"{pre_cont}└─ Code\n"
|
s += f"{pre_cont}└─ Code\n"
|
||||||
for code in self._code[:-1]:
|
for code in self._code[:-1]:
|
||||||
|
|
@ -390,48 +257,7 @@ class FunctionBlock:
|
||||||
parent_table: SymbolTable,
|
parent_table: SymbolTable,
|
||||||
) -> "FunctionBlock":
|
) -> "FunctionBlock":
|
||||||
symbol_table = SymbolTable(parent_table)
|
symbol_table = SymbolTable(parent_table)
|
||||||
for param in func.params:
|
|
||||||
try:
|
|
||||||
symbol_table.add(Symbol(
|
|
||||||
param.identifier.content, SymbolType.variable, param))
|
|
||||||
except KeyError:
|
|
||||||
raise VariableAlreadyDeclared(
|
|
||||||
param,
|
|
||||||
symbol_table.get(param.identifier.content).definition,
|
|
||||||
)
|
|
||||||
members: list[syntactical_analyzer.LetStatement] = []
|
|
||||||
code: list[syntactical_analyzer.Statement] = []
|
|
||||||
for statement in func.code:
|
|
||||||
if isinstance(statement, syntactical_analyzer.LetStatement):
|
|
||||||
try:
|
|
||||||
symbol_table.add(Symbol(
|
|
||||||
statement.identifier.content,
|
|
||||||
SymbolType.variable, statement,
|
|
||||||
))
|
|
||||||
except KeyError:
|
|
||||||
raise VariableAlreadyDeclared(
|
|
||||||
statement,
|
|
||||||
symbol_table.get(
|
|
||||||
statement.identifier.content
|
|
||||||
).definition,
|
|
||||||
)
|
|
||||||
if statement.static:
|
|
||||||
members.append(statement)
|
|
||||||
else:
|
|
||||||
code.append(statement)
|
|
||||||
else:
|
|
||||||
code.append(statement)
|
|
||||||
|
|
||||||
return FunctionBlock(
|
|
||||||
func.identifier,
|
|
||||||
func.params,
|
|
||||||
func.return_type_pointer,
|
|
||||||
func.return_type,
|
|
||||||
members,
|
|
||||||
code,
|
|
||||||
func.file_info,
|
|
||||||
symbol_table,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class File:
|
class File:
|
||||||
|
|
@ -524,55 +350,5 @@ class File:
|
||||||
return file
|
return file
|
||||||
|
|
||||||
|
|
||||||
def _get_all_operands(
|
|
||||||
expression: syntactical_analyzer.Expression,
|
|
||||||
) -> list[syntactical_analyzer.Expression]:
|
|
||||||
if isinstance(
|
|
||||||
expression,
|
|
||||||
BaseValues + (
|
|
||||||
syntactical_analyzer.LoopStatements,
|
|
||||||
syntactical_analyzer.NoOperation,
|
|
||||||
),
|
|
||||||
):
|
|
||||||
return [expression]
|
|
||||||
elif isinstance(expression, syntactical_analyzer.UnaryExpression):
|
|
||||||
return _get_all_operands(expression.operand)
|
|
||||||
elif isinstance(expression, syntactical_analyzer.BinaryExpression):
|
|
||||||
return (
|
|
||||||
_get_all_operands(expression.operand1) +
|
|
||||||
_get_all_operands(expression.operand2)
|
|
||||||
)
|
|
||||||
elif isinstance(expression, syntactical_analyzer.TernaryExpression):
|
|
||||||
return (
|
|
||||||
_get_all_operands(expression.operand1) +
|
|
||||||
_get_all_operands(expression.operand2) +
|
|
||||||
_get_all_operands(expression.operand3)
|
|
||||||
)
|
|
||||||
|
|
||||||
def _flatten_statement(
|
|
||||||
statement: syntactical_analyzer.Statement,
|
|
||||||
) -> list[syntactical_analyzer.Statement]:
|
|
||||||
if isinstance(statement, NestableCodeBlocks):
|
|
||||||
return [statement]
|
|
||||||
elif isinstance(
|
|
||||||
statement,
|
|
||||||
BaseValues + (
|
|
||||||
syntactical_analyzer.LoopStatements,
|
|
||||||
syntactical_analyzer.NoOperation,
|
|
||||||
),
|
|
||||||
):
|
|
||||||
return [statement]
|
|
||||||
elif isinstance(statement, syntactical_analyzer.UnaryExpression):
|
|
||||||
if isinstance(statement.operand, BaseValues):
|
|
||||||
return [statement]
|
|
||||||
elif isinstance(statement, syntactical_analyzer.BinaryExpression):
|
|
||||||
if (
|
|
||||||
statement.operator.content ==
|
|
||||||
syntactical_analyzer.BinaryOperatorEnum.MemberOf
|
|
||||||
):
|
|
||||||
pass
|
|
||||||
elif isinstance(statement, syntactical_analyzer.TernaryExpression):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def semantical_analyzer(syntax_tree: syntactical_analyzer.File) -> File:
|
def semantical_analyzer(syntax_tree: syntactical_analyzer.File) -> File:
|
||||||
return File._sa(syntax_tree)
|
return File._sa(syntax_tree)
|
||||||
|
|
|
||||||
|
|
@ -2,38 +2,12 @@
|
||||||
# Feb 2024
|
# Feb 2024
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Sequence
|
from typing import Iterable, Sequence
|
||||||
|
|
||||||
from .compiler_types import CompilerError, FileInfo
|
from .compiler_types import CompilerError, FileInfo
|
||||||
from . import lexer
|
from . import lexer
|
||||||
|
|
||||||
|
|
||||||
type NestableCodeBlock = ForBlock | WhileBlock | DoBlock | IfBlock
|
|
||||||
|
|
||||||
type Literal = (
|
|
||||||
BuiltInConst |
|
|
||||||
NumberLiteral |
|
|
||||||
CharLiteral |
|
|
||||||
StringLiteral
|
|
||||||
)
|
|
||||||
|
|
||||||
type Expression = (
|
|
||||||
Literal |
|
|
||||||
Identifier |
|
|
||||||
UnaryExpression |
|
|
||||||
BinaryExpression |
|
|
||||||
TernaryExpression |
|
|
||||||
FunctionCall |
|
|
||||||
NoOperation
|
|
||||||
)
|
|
||||||
|
|
||||||
type Statement = Expression | LetStatement | LoopStatements | NestableCodeBlock
|
|
||||||
|
|
||||||
type DataType = BuiltInDataType | Identifier
|
|
||||||
|
|
||||||
type Operator = UnaryOperator | BinaryOperator | TernaryOperator
|
|
||||||
|
|
||||||
|
|
||||||
class SyntaxError(CompilerError):
|
class SyntaxError(CompilerError):
|
||||||
|
|
||||||
_compiler_error_type = "Syntax"
|
_compiler_error_type = "Syntax"
|
||||||
|
|
@ -155,6 +129,30 @@ class UnexpectedPunctuation(_UnexpectedTokenBase):
|
||||||
class ExpressionError(Exception): pass
|
class ExpressionError(Exception): pass
|
||||||
|
|
||||||
|
|
||||||
|
type NestableCodeBlock = ForBlock | WhileBlock | DoBlock | IfBlock
|
||||||
|
|
||||||
|
type Literal = (
|
||||||
|
BuiltInConst |
|
||||||
|
NumberLiteral |
|
||||||
|
CharLiteral |
|
||||||
|
StringLiteral
|
||||||
|
)
|
||||||
|
|
||||||
|
type Expression = (
|
||||||
|
Literal |
|
||||||
|
Identifier |
|
||||||
|
UnaryExpression |
|
||||||
|
BinaryExpression |
|
||||||
|
TernaryExpression |
|
||||||
|
FunctionCall |
|
||||||
|
NoOperation
|
||||||
|
)
|
||||||
|
|
||||||
|
type Statement = Expression | LetStatement | LoopStatements | NestableCodeBlock
|
||||||
|
|
||||||
|
type DataType = BuiltInDataType | Identifier
|
||||||
|
|
||||||
|
|
||||||
class BuiltInConstEnum(Enum):
|
class BuiltInConstEnum(Enum):
|
||||||
ConstTrue = "True"
|
ConstTrue = "True"
|
||||||
ConstFalse = "False"
|
ConstFalse = "False"
|
||||||
|
|
@ -240,10 +238,6 @@ class UnaryOperator:
|
||||||
self._content = content
|
self._content = content
|
||||||
self._file_info = file_info
|
self._file_info = file_info
|
||||||
|
|
||||||
@property
|
|
||||||
def content(self) -> PostfixUnaryOperatorEnum | PrefixUnaryOperatorEnum:
|
|
||||||
return self._content
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def file_info(self) -> FileInfo: return self._file_info
|
def file_info(self) -> FileInfo: return self._file_info
|
||||||
|
|
||||||
|
|
@ -302,9 +296,6 @@ class BinaryOperator:
|
||||||
self._content = content
|
self._content = content
|
||||||
self._file_info = file_info
|
self._file_info = file_info
|
||||||
|
|
||||||
@property
|
|
||||||
def content(self) -> BinaryOperatorEnum: return self._content
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def file_info(self) -> FileInfo: return self._file_info
|
def file_info(self) -> FileInfo: return self._file_info
|
||||||
|
|
||||||
|
|
@ -333,9 +324,6 @@ class TernaryOperator:
|
||||||
self._content = content
|
self._content = content
|
||||||
self._file_info = file_info
|
self._file_info = file_info
|
||||||
|
|
||||||
@property
|
|
||||||
def content(self) -> TernaryOperatorEnum: return self._content
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def file_info(self) -> FileInfo: return self._file_info
|
def file_info(self) -> FileInfo: return self._file_info
|
||||||
|
|
||||||
|
|
@ -632,18 +620,6 @@ class TernaryExpression:
|
||||||
self._operand3 = operand3
|
self._operand3 = operand3
|
||||||
self._file_info = file_info
|
self._file_info = file_info
|
||||||
|
|
||||||
@property
|
|
||||||
def operator(self) -> TernaryOperator: return self._operator
|
|
||||||
|
|
||||||
@property
|
|
||||||
def operand1(self) -> Expression: return self._operand1
|
|
||||||
|
|
||||||
@property
|
|
||||||
def operand2(self) -> Expression: return self._operand2
|
|
||||||
|
|
||||||
@property
|
|
||||||
def operand3(self) -> Expression: return self._operand3
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def file_info(self) -> FileInfo: return self._file_info
|
def file_info(self) -> FileInfo: return self._file_info
|
||||||
|
|
||||||
|
|
@ -674,15 +650,6 @@ class BinaryExpression:
|
||||||
self._operand2 = operand2
|
self._operand2 = operand2
|
||||||
self._file_info = file_info
|
self._file_info = file_info
|
||||||
|
|
||||||
@property
|
|
||||||
def operator(self) -> BinaryOperator: return self._operator
|
|
||||||
|
|
||||||
@property
|
|
||||||
def operand1(self) -> Expression: return self._operand1
|
|
||||||
|
|
||||||
@property
|
|
||||||
def operand2(self) -> Expression: return self._operand2
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def file_info(self) -> FileInfo: return self._file_info
|
def file_info(self) -> FileInfo: return self._file_info
|
||||||
|
|
||||||
|
|
@ -709,12 +676,6 @@ class UnaryExpression:
|
||||||
self._operand = operand
|
self._operand = operand
|
||||||
self._file_info = file_info
|
self._file_info = file_info
|
||||||
|
|
||||||
@property
|
|
||||||
def operator(self) -> UnaryOperator: return self._operator
|
|
||||||
|
|
||||||
@property
|
|
||||||
def operand(self) -> Expression: return self._operand
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def file_info(self) -> FileInfo: return self._file_info
|
def file_info(self) -> FileInfo: return self._file_info
|
||||||
|
|
||||||
|
|
@ -730,7 +691,7 @@ class LetStatement:
|
||||||
_type: DataType
|
_type: DataType
|
||||||
_pointer: bool
|
_pointer: bool
|
||||||
_static: bool
|
_static: bool
|
||||||
_assignment: Literal | None
|
_assignment: Expression | None
|
||||||
_file_info: FileInfo
|
_file_info: FileInfo
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
@ -749,18 +710,12 @@ class LetStatement:
|
||||||
self._assignment = assignment
|
self._assignment = assignment
|
||||||
self._file_info = file_info
|
self._file_info = file_info
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self) -> Identifier: return self._identifier
|
|
||||||
|
|
||||||
@property
|
|
||||||
def assignment(self) -> Literal | None: return self._assignment
|
|
||||||
|
|
||||||
@property
|
|
||||||
def static(self) -> bool: return self._static
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def file_info(self) -> FileInfo: return self._file_info
|
def file_info(self) -> FileInfo: return self._file_info
|
||||||
|
|
||||||
|
@property
|
||||||
|
def identifier(self) -> Identifier: return self._identifier
|
||||||
|
|
||||||
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
||||||
s: str = f"{pre} Let Statement: {self._identifier}\n"
|
s: str = f"{pre} Let Statement: {self._identifier}\n"
|
||||||
s += pre_cont
|
s += pre_cont
|
||||||
|
|
@ -873,9 +828,6 @@ class ForPreDef:
|
||||||
@property
|
@property
|
||||||
def file_info(self) -> FileInfo: return self._file_info
|
def file_info(self) -> FileInfo: return self._file_info
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self) -> Identifier: return self._identifier
|
|
||||||
|
|
||||||
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
||||||
s: str = f"{pre} For Loop Pre-Definition: {self._identifier}\n"
|
s: str = f"{pre} For Loop Pre-Definition: {self._identifier}\n"
|
||||||
if self._assignment: s += f"{pre_cont}├─ Type: "
|
if self._assignment: s += f"{pre_cont}├─ Type: "
|
||||||
|
|
|
||||||
|
|
@ -40,4 +40,4 @@ class tty(Device):
|
||||||
elif index & 0xf == 0xe:
|
elif index & 0xf == 0xe:
|
||||||
print(value)
|
print(value)
|
||||||
elif index & 0xf == 0xf:
|
elif index & 0xf == 0xf:
|
||||||
print(chr(value & 0x7f), end='')
|
print(chr(value), end='')
|
||||||
|
|
|
||||||
|
|
@ -269,13 +269,13 @@ class Computer:
|
||||||
elif instruction & 0xFC0 == 0x80: self.LDI(instruction & 0x3F)
|
elif instruction & 0xFC0 == 0x80: self.LDI(instruction & 0x3F)
|
||||||
elif instruction & 0xFC0 == 0xC0: self.LIL(instruction & 0x3F)
|
elif instruction & 0xFC0 == 0xC0: self.LIL(instruction & 0x3F)
|
||||||
elif instruction & 0xFC0 == 0x100:
|
elif instruction & 0xFC0 == 0x100:
|
||||||
self.LSH(instruction & 0x7, (instruction & 0x38) >> 3)
|
self.LSH((instruction & 0x38) >> 3, instruction & 0x7)
|
||||||
elif instruction & 0xFC0 == 0x140:
|
elif instruction & 0xFC0 == 0x140:
|
||||||
self.RSH(instruction & 0x7, (instruction & 0x38) >> 3)
|
self.RSH((instruction & 0x38) >> 3, instruction & 0x7)
|
||||||
elif instruction & 0xFC0 == 0x180:
|
elif instruction & 0xFC0 == 0x180:
|
||||||
self.INC(instruction & 0x7, (instruction & 0x38) >> 3)
|
self.INC((instruction & 0x38) >> 3, instruction & 0x7)
|
||||||
elif instruction & 0xFC0 == 0x1C0:
|
elif instruction & 0xFC0 == 0x1C0:
|
||||||
self.DEC(instruction & 0x7, (instruction & 0x38) >> 3)
|
self.DEC((instruction & 0x38) >> 3, instruction & 0x7)
|
||||||
elif instruction & 0xE00 == 0x200:
|
elif instruction & 0xE00 == 0x200:
|
||||||
self.AND(
|
self.AND(
|
||||||
instruction & 0x7,
|
instruction & 0x7,
|
||||||
|
|
@ -429,11 +429,11 @@ class Computer:
|
||||||
self.program_counter += 1
|
self.program_counter += 1
|
||||||
|
|
||||||
def POP(self, REG: int):
|
def POP(self, REG: int):
|
||||||
self.set_reg(REG, self._mem[self.stack_pointer])
|
self._mem[self.stack_pointer] = self.get_reg(REG)
|
||||||
self.program_counter += 1
|
self.program_counter += 1
|
||||||
|
|
||||||
def PSH(self, REG: int):
|
def PSH(self, REG: int):
|
||||||
self._mem[self.stack_pointer] = self.get_reg(REG)
|
self.set_reg(REG, self._mem[self.stack_pointer])
|
||||||
self.program_counter += 1
|
self.program_counter += 1
|
||||||
|
|
||||||
def LIU(self, Immediate: int):
|
def LIU(self, Immediate: int):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue