More compiler fixes
This commit is contained in:
parent
c2051ffce4
commit
e833d2e311
|
@ -2,3 +2,4 @@
|
||||||
docs/*.pdf
|
docs/*.pdf
|
||||||
__pycache__
|
__pycache__
|
||||||
bin
|
bin
|
||||||
|
.vscode
|
||||||
|
|
|
@ -237,35 +237,36 @@ and a `literal`.
|
||||||
#### If Statement
|
#### If Statement
|
||||||
|
|
||||||
An `if statement` begins with the `if` keyword, followed by its condition, an
|
An `if statement` begins with the `if` keyword, followed by its condition, an
|
||||||
`expression` enclosed in parentheses (`(` and `)`), then a list enclosed in
|
`expression` enclosed in parentheses (`(` and `)`), then a single `statement`
|
||||||
curly braces (`{` and `}`) of `statements`. It may then optionally be followed
|
or a list enclosed in curly braces (`{` and `}`) of `statements`. It may then
|
||||||
by an `else block`.
|
optionally be followed by an `else block`.
|
||||||
|
|
||||||
#### Do Loop
|
#### Do Loop
|
||||||
|
|
||||||
A `do loop` begins with the `do` keyword, followed by a list enclosed in curly
|
A `do loop` begins with the `do` keyword, followed by a single `statement` or a
|
||||||
braces (`{` and `}`) of `statements`. It is then followed with the `while`
|
list enclosed in curly braces (`{` and `}`) of `statements`. It is then followed
|
||||||
keyword, then by its condition, an `expression` enclosed in parentheses
|
with the `while` keyword, then by its condition, an `expression` enclosed in
|
||||||
(`(` and `)`). It may then optionally be followed by another list enclosed in
|
parentheses (`(` and `)`). It may then optionally be followed by a single
|
||||||
curly braces (`{` and `}`) of `statements`. Finally the `do loop` may optionally
|
`statement` or another list enclosed in curly braces (`{` and `}`) of
|
||||||
be followed by an `else block`.
|
`statements`. Finally the `do loop` may optionally be followed by an
|
||||||
|
`else block`.
|
||||||
|
|
||||||
#### While Loop
|
#### While Loop
|
||||||
|
|
||||||
A `while loop` begins with the `while` keyword, followed by its condition, an
|
A `while loop` begins with the `while` keyword, followed by its condition, an
|
||||||
`expression` enclosed in parentheses (`(` and `)`), then a list enclosed in
|
`expression` enclosed in parentheses (`(` and `)`), then a single `statement`
|
||||||
curly braces (`{` and `}`) of `statements`. It may then
|
or a list enclosed in curly braces (`{` and `}`) of `statements`. It may then
|
||||||
optionally be followed by an `else block`.
|
optionally be followed by an `else block`.
|
||||||
|
|
||||||
#### For Loop
|
#### For Loop
|
||||||
|
|
||||||
A `for loop` begins with the `for` keyword, followed by three expressions
|
A `for loop` begins with the `for` keyword, followed by three expressions
|
||||||
enclosed in parentheses (`(` and `)`), separated by semicolons (`;`). The first
|
enclosed in parentheses (`(` and `)`), separated by semicolons (`;`). The
|
||||||
expression is a *pre-loop expression*, the second is its condition which is a
|
first expression is a *pre-loop expression*, the second is its condition which
|
||||||
normal `expression`, and the last is its post-loop expression which is another
|
is a normal `expression`, and the last is its post-loop expression which is
|
||||||
normal `expression`. It is ended with a list enclosed in curly braces
|
another normal `expression`. It is ended with a single `statement` or a list
|
||||||
(`{` and `}`) of `statements`. It may then optionally be
|
enclosed in curly braces (`{` and `}`) of `statements`. It may then optionally
|
||||||
followed by an `else block`.
|
be followed by an `else block`.
|
||||||
|
|
||||||
##### Pre-Loop Expression
|
##### Pre-Loop Expression
|
||||||
|
|
||||||
|
@ -275,8 +276,8 @@ then an equal sign (`=`) followed by an `expression`.
|
||||||
|
|
||||||
#### Else Block
|
#### Else Block
|
||||||
|
|
||||||
An `else block` begins with the `else` keyword, followed by a list enclosed in
|
An `else block` begins with the `else` keyword, followed by a single
|
||||||
curly braces (`{` and `}`) of `statements`.
|
`statement` or a list enclosed in curly braces (`{` and `}`) of `statements`.
|
||||||
|
|
||||||
#### Let Statement
|
#### Let Statement
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,131 @@ fn test_func2() -> Point {
|
||||||
test = '"';
|
test = '"';
|
||||||
test = "Hello World!";
|
test = "Hello World!";
|
||||||
test = "This is \"cool\"!";
|
test = "This is \"cool\"!";
|
||||||
|
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (test >= 10);
|
||||||
|
|
||||||
|
if (test >= 20)
|
||||||
|
test -= 2;
|
||||||
|
test -= 3;
|
||||||
|
|
||||||
|
if (test >= 20)
|
||||||
|
test -= 2;
|
||||||
|
else
|
||||||
|
test -= 3;
|
||||||
|
|
||||||
|
if (test >= 30) {
|
||||||
|
test -= 4;
|
||||||
|
test -= 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test >= 40) {
|
||||||
|
test -= 6;
|
||||||
|
} else {
|
||||||
|
test += 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test >= 50) {
|
||||||
|
test -= 7;
|
||||||
|
} else if (test >= 60) {
|
||||||
|
test--;
|
||||||
|
} else {
|
||||||
|
test += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
test += 17;
|
||||||
|
while (test);
|
||||||
|
|
||||||
|
do
|
||||||
|
test += 18;
|
||||||
|
while (test)
|
||||||
|
test += 19;
|
||||||
|
|
||||||
|
do
|
||||||
|
test += 20;
|
||||||
|
while (test)
|
||||||
|
else
|
||||||
|
test += 21;
|
||||||
|
|
||||||
|
do
|
||||||
|
test += 22;
|
||||||
|
while (test)
|
||||||
|
test += 23;
|
||||||
|
else
|
||||||
|
test += 24;
|
||||||
|
|
||||||
|
do
|
||||||
|
test += 25;
|
||||||
|
while (test)
|
||||||
|
test += 26;
|
||||||
|
else if (test == 32)
|
||||||
|
test += 27;
|
||||||
|
|
||||||
|
do {
|
||||||
|
test += 18;
|
||||||
|
} while (test);
|
||||||
|
|
||||||
|
do {
|
||||||
|
test += 29;
|
||||||
|
} while (test) {
|
||||||
|
test += 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
test += 31;
|
||||||
|
} while (test)
|
||||||
|
else {
|
||||||
|
test += 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
test += 33;
|
||||||
|
} while (test) {
|
||||||
|
test += 34;
|
||||||
|
} else {
|
||||||
|
test += 35;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (test >= 20)
|
||||||
|
test -= 2;
|
||||||
|
test -= 3;
|
||||||
|
|
||||||
|
while (test >= 20)
|
||||||
|
test -= 2;
|
||||||
|
else
|
||||||
|
test -= 3;
|
||||||
|
|
||||||
|
while (test >= 30) {
|
||||||
|
test -= 4;
|
||||||
|
test -= 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (test >= 40) {
|
||||||
|
test -= 6;
|
||||||
|
} else {
|
||||||
|
test += 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i: int = 0; i < length; i++)
|
||||||
|
$(inData + i) ^= $(pass + ((i + offset) % pLength));
|
||||||
|
|
||||||
|
for (i: int = 0; i < length; i++)
|
||||||
|
$(inData + i) ^= $(pass + ((i + offset) % pLength));
|
||||||
|
else
|
||||||
|
test = 16;
|
||||||
|
|
||||||
|
for (i: int; i < length; i++) {
|
||||||
|
$(inData + i) ^= $(pass + ((i + offset) % pLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
$(inData + i) ^= $(pass + ((i + offset) % pLength));
|
||||||
|
} else {
|
||||||
|
test = 17;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> int {
|
fn main() -> int {
|
||||||
|
|
|
@ -142,7 +142,8 @@ type Expression = (
|
||||||
UnaryExpression |
|
UnaryExpression |
|
||||||
BinaryExpression |
|
BinaryExpression |
|
||||||
TernaryExpression |
|
TernaryExpression |
|
||||||
FunctionCall
|
FunctionCall |
|
||||||
|
NoOperation
|
||||||
)
|
)
|
||||||
|
|
||||||
type Statement = Expression | LetStatement | LoopStatements | NestableCodeBlock
|
type Statement = Expression | LetStatement | LoopStatements | NestableCodeBlock
|
||||||
|
@ -167,7 +168,7 @@ class LoopStatements(Enum):
|
||||||
BreakStatement = "break"
|
BreakStatement = "break"
|
||||||
|
|
||||||
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
||||||
s: str = f"{pre} {self.value.upper()}\n"
|
s: str = f"{pre} {self.value.lower()}\n"
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
@ -276,6 +277,13 @@ _Operator_Precedence: tuple[
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class NoOperation:
|
||||||
|
|
||||||
|
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
||||||
|
s: str = f"{pre} Nop\n"
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
class Identifier:
|
class Identifier:
|
||||||
|
|
||||||
_content: str
|
_content: str
|
||||||
|
@ -533,14 +541,14 @@ class ForPreDef:
|
||||||
_identifier: Identifier
|
_identifier: Identifier
|
||||||
_type: DataType
|
_type: DataType
|
||||||
_pointer: bool
|
_pointer: bool
|
||||||
_assignment: Expression
|
_assignment: Expression | None
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
identifier: Identifier,
|
identifier: Identifier,
|
||||||
type: DataType,
|
type: DataType,
|
||||||
pointer: bool,
|
pointer: bool,
|
||||||
assignment: Expression,
|
assignment: Expression | None,
|
||||||
):
|
):
|
||||||
self._identifier = identifier
|
self._identifier = identifier
|
||||||
self._type = type
|
self._type = type
|
||||||
|
@ -549,10 +557,11 @@ class ForPreDef:
|
||||||
|
|
||||||
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"
|
||||||
s += f"{pre_cont}├─ Type: "
|
if self._assignment: s += f"{pre_cont}├─ Type: "
|
||||||
|
else: s += f"{pre_cont}└─ Type: "
|
||||||
if self._pointer: s+= "@"
|
if self._pointer: s+= "@"
|
||||||
s += f"{self._type}\n"
|
s += f"{self._type}\n"
|
||||||
s += f"{pre_cont}└─ Value: {self._assignment}\n"
|
if self._assignment: s += f"{pre_cont}└─ Value: {self._assignment}\n"
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
@ -579,7 +588,7 @@ class ForBlock:
|
||||||
self._else = else_block
|
self._else = else_block
|
||||||
|
|
||||||
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
||||||
s: str = f"{pre} If Statement\n"
|
s: str = f"{pre} For Loop\n"
|
||||||
if self._code or self._else is not None:
|
if self._code or self._else is not None:
|
||||||
cond_pre = f"{pre_cont}├─"
|
cond_pre = f"{pre_cont}├─"
|
||||||
cond_pre_cont = f"{pre_cont}│ "
|
cond_pre_cont = f"{pre_cont}│ "
|
||||||
|
@ -675,12 +684,8 @@ class DoBlock:
|
||||||
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
def tree_str(self, pre: str = "", pre_cont: str = "") -> str:
|
||||||
s: str = f"{pre} Do Loop\n"
|
s: str = f"{pre} Do Loop\n"
|
||||||
if self._first_code:
|
if self._first_code:
|
||||||
if self._second_code or self._else is not None:
|
|
||||||
s += f"{pre_cont}├─ First Code\n"
|
s += f"{pre_cont}├─ First Code\n"
|
||||||
code_pre = f"{pre_cont}│ "
|
code_pre = f"{pre_cont}│ "
|
||||||
else:
|
|
||||||
s += f"{pre_cont}└─ First Code\n"
|
|
||||||
code_pre = f"{pre_cont} "
|
|
||||||
for code in self._first_code[:-1]:
|
for code in self._first_code[:-1]:
|
||||||
s += code.tree_str(code_pre + "├─", code_pre + "│ ")
|
s += code.tree_str(code_pre + "├─", code_pre + "│ ")
|
||||||
s += self._first_code[-1].tree_str(
|
s += self._first_code[-1].tree_str(
|
||||||
|
@ -950,7 +955,7 @@ class File:
|
||||||
self._children = children[:]
|
self._children = children[:]
|
||||||
|
|
||||||
def tree_str(self) -> str:
|
def tree_str(self) -> str:
|
||||||
s: str = "File\n"
|
s: str = " File\n"
|
||||||
if self._children:
|
if self._children:
|
||||||
for child in self._children[:-1]:
|
for child in self._children[:-1]:
|
||||||
s += child.tree_str("├─", "│ ")
|
s += child.tree_str("├─", "│ ")
|
||||||
|
@ -1353,31 +1358,59 @@ def _statement_sa(tokens: list[lexer.Token]) -> Statement:
|
||||||
return LoopStatements(key)
|
return LoopStatements(key)
|
||||||
case 'if':
|
case 'if':
|
||||||
condition = _expression_sa(_get_nested_group(tokens))
|
condition = _expression_sa(_get_nested_group(tokens))
|
||||||
code = _code_block_sa(tokens)
|
if tokens[0].value == '{':
|
||||||
if tokens[0].value == 'else':
|
code = _code_block_sa(_get_nested_group(tokens, ('{','}')))
|
||||||
else_block = ElseBlock(_code_block_sa(tokens))
|
else:
|
||||||
|
code = [_statement_sa(tokens)]
|
||||||
|
if tokens and tokens[0].value == 'else':
|
||||||
|
token = tokens.pop(0)
|
||||||
|
if tokens[0].value == '{':
|
||||||
|
else_block = ElseBlock(_code_block_sa(_get_nested_group(
|
||||||
|
tokens, ('{','}'))))
|
||||||
|
else:
|
||||||
|
else_block = ElseBlock([_statement_sa(tokens)])
|
||||||
else:
|
else:
|
||||||
else_block = None
|
else_block = None
|
||||||
return IfBlock(condition, code, else_block)
|
return IfBlock(condition, code, else_block)
|
||||||
case 'do':
|
case 'do':
|
||||||
code1 = _code_block_sa(tokens)
|
if tokens[0].value == '{':
|
||||||
|
code1 = _code_block_sa(_get_nested_group(tokens, ('{','}')))
|
||||||
|
else:
|
||||||
|
code1 = [_statement_sa(tokens)]
|
||||||
token = tokens.pop(0)
|
token = tokens.pop(0)
|
||||||
_assert_token(ExpectedKeyword, token, 'while')
|
_assert_token(ExpectedKeyword, token, 'while')
|
||||||
condition = _expression_sa(_get_nested_group(tokens))
|
condition = _expression_sa(_get_nested_group(tokens))
|
||||||
if tokens[0].value == '{':
|
if tokens[0].value == '{':
|
||||||
code2 = _code_block_sa(tokens)
|
code2 = _code_block_sa(_get_nested_group(tokens, ('{','}')))
|
||||||
|
elif tokens[0].value != 'else':
|
||||||
|
code2 = [_statement_sa(tokens)]
|
||||||
|
if isinstance(code2[0], NoOperation):
|
||||||
|
code2 = None
|
||||||
else:
|
else:
|
||||||
code2 = None
|
code2 = None
|
||||||
if tokens[0].value == 'else':
|
if tokens and tokens[0].value == 'else':
|
||||||
else_block = ElseBlock(_code_block_sa(tokens))
|
token = tokens.pop(0)
|
||||||
|
if tokens[0].value == '{':
|
||||||
|
else_block = ElseBlock(_code_block_sa(_get_nested_group(
|
||||||
|
tokens, ('{','}'))))
|
||||||
|
else:
|
||||||
|
else_block = ElseBlock([_statement_sa(tokens)])
|
||||||
else:
|
else:
|
||||||
else_block = None
|
else_block = None
|
||||||
return DoBlock(code1, condition, code2, else_block)
|
return DoBlock(code1, condition, code2, else_block)
|
||||||
case 'while':
|
case 'while':
|
||||||
condition = _expression_sa(_get_nested_group(tokens))
|
condition = _expression_sa(_get_nested_group(tokens))
|
||||||
code = _code_block_sa(tokens)
|
if tokens[0].value == '{':
|
||||||
if tokens[0].value == 'else':
|
code = _code_block_sa(_get_nested_group(tokens, ('{','}')))
|
||||||
else_block = ElseBlock(_code_block_sa(tokens))
|
else:
|
||||||
|
code = [_statement_sa(tokens)]
|
||||||
|
if tokens and tokens[0].value == 'else':
|
||||||
|
token = tokens.pop(0)
|
||||||
|
if tokens[0].value == '{':
|
||||||
|
else_block = ElseBlock(_code_block_sa(_get_nested_group(
|
||||||
|
tokens, ('{','}'))))
|
||||||
|
else:
|
||||||
|
else_block = ElseBlock([_statement_sa(tokens)])
|
||||||
else:
|
else:
|
||||||
else_block = None
|
else_block = None
|
||||||
return WhileBlock(condition, code, else_block)
|
return WhileBlock(condition, code, else_block)
|
||||||
|
@ -1388,9 +1421,8 @@ def _statement_sa(tokens: list[lexer.Token]) -> Statement:
|
||||||
while token.value != ';':
|
while token.value != ';':
|
||||||
pre_loop_tokens.append(token)
|
pre_loop_tokens.append(token)
|
||||||
token = three_expressions.pop(0)
|
token = three_expressions.pop(0)
|
||||||
token = three_expressions.pop(0)
|
|
||||||
if (
|
if (
|
||||||
type(pre_loop_tokens[0]) is lexer.Identifier and
|
isinstance(pre_loop_tokens[0], lexer.Identifier) and
|
||||||
pre_loop_tokens[1].value == ':'
|
pre_loop_tokens[1].value == ':'
|
||||||
):
|
):
|
||||||
identifier = Identifier(pre_loop_tokens.pop(0).value)
|
identifier = Identifier(pre_loop_tokens.pop(0).value)
|
||||||
|
@ -1401,6 +1433,8 @@ def _statement_sa(tokens: list[lexer.Token]) -> Statement:
|
||||||
token = pre_loop_tokens.pop(0)
|
token = pre_loop_tokens.pop(0)
|
||||||
_assert_token(ExpectedPunctuation, token, '=')
|
_assert_token(ExpectedPunctuation, token, '=')
|
||||||
pre_loop_expr = _expression_sa(pre_loop_tokens)
|
pre_loop_expr = _expression_sa(pre_loop_tokens)
|
||||||
|
else:
|
||||||
|
pre_loop_expr = None
|
||||||
pre_loop = ForPreDef(
|
pre_loop = ForPreDef(
|
||||||
identifier,
|
identifier,
|
||||||
data_type,
|
data_type,
|
||||||
|
@ -1409,16 +1443,24 @@ def _statement_sa(tokens: list[lexer.Token]) -> Statement:
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
pre_loop = _expression_sa(pre_loop_tokens)
|
pre_loop = _expression_sa(pre_loop_tokens)
|
||||||
|
token = three_expressions.pop(0)
|
||||||
loop_condition_tokens: list[lexer.Token] = []
|
loop_condition_tokens: list[lexer.Token] = []
|
||||||
while token.value != ';':
|
while token.value != ';':
|
||||||
loop_condition_tokens.append(token)
|
loop_condition_tokens.append(token)
|
||||||
token = three_expressions.pop(0)
|
token = three_expressions.pop(0)
|
||||||
token = three_expressions.pop(0)
|
|
||||||
condition = _expression_sa(loop_condition_tokens)
|
condition = _expression_sa(loop_condition_tokens)
|
||||||
post_loop = _expression_sa(three_expressions)
|
post_loop = _expression_sa(three_expressions)
|
||||||
code = _code_block_sa(tokens)
|
if tokens[0].value == '{':
|
||||||
if tokens[0].value == 'else':
|
code = _code_block_sa(_get_nested_group(tokens, ('{','}')))
|
||||||
else_block = ElseBlock(_code_block_sa(tokens))
|
else:
|
||||||
|
code = [_statement_sa(tokens)]
|
||||||
|
if tokens and tokens[0].value == 'else':
|
||||||
|
token = tokens.pop(0)
|
||||||
|
if tokens[0].value == '{':
|
||||||
|
else_block = ElseBlock(_code_block_sa(_get_nested_group(
|
||||||
|
tokens, ('{','}'))))
|
||||||
|
else:
|
||||||
|
else_block = ElseBlock([_statement_sa(tokens)])
|
||||||
else:
|
else:
|
||||||
else_block = None
|
else_block = None
|
||||||
return ForBlock(
|
return ForBlock(
|
||||||
|
@ -1434,6 +1476,8 @@ def _statement_sa(tokens: list[lexer.Token]) -> Statement:
|
||||||
'while',
|
'while',
|
||||||
'for',
|
'for',
|
||||||
] + [i.value for i in BuiltInConst])
|
] + [i.value for i in BuiltInConst])
|
||||||
|
elif token.value == ';':
|
||||||
|
return NoOperation()
|
||||||
expr_tokens: list[lexer.Token] = [token] + _get_to_symbol(tokens)
|
expr_tokens: list[lexer.Token] = [token] + _get_to_symbol(tokens)
|
||||||
return _expression_sa(expr_tokens)
|
return _expression_sa(expr_tokens)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue