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