forked from luna/jorts
finish "parsing" of hello.jt
the AST is very ugly as it is rn. had to remove the cleanups or else its all [[None], [None], ...] ok im startnig to give up on doing handwritten lmao help - add TokenType.string - add read_value, read_statement, fix block reading
This commit is contained in:
parent
c2678fe360
commit
a7034db0eb
4 changed files with 61 additions and 15 deletions
|
@ -5,6 +5,7 @@ import io
|
|||
|
||||
// main can return int or void, void mains are handled by jortsc
|
||||
fn main () -> int {
|
||||
io.puts("pants")
|
||||
// todo: put it back to io.puts
|
||||
ioputs("pants")
|
||||
0
|
||||
}
|
||||
|
|
|
@ -27,3 +27,19 @@ class Identifier:
|
|||
@dataclass
|
||||
class Import:
|
||||
module: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class String:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Number:
|
||||
value: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class FunctionCall:
|
||||
function: str
|
||||
args: list
|
||||
|
|
|
@ -13,6 +13,7 @@ class TokenType(Enum):
|
|||
comment_end = auto()
|
||||
whitespace = auto()
|
||||
number = auto()
|
||||
string = auto()
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -50,7 +51,7 @@ TOKENS = [
|
|||
(r'\-\>', TokenType.reserved),
|
||||
(r'\.', TokenType.reserved),
|
||||
|
||||
(r'\"[^\n]*\"', TokenType.reserved),
|
||||
(r'\"[^\n]*\"', TokenType.string),
|
||||
|
||||
# basic math ops
|
||||
(r'[\+\-\/\*]', TokenType.reserved),
|
||||
|
|
|
@ -2,7 +2,8 @@ from typing import Optional, Any, List
|
|||
|
||||
from jortsc.parser.lexer import Token, TokenType
|
||||
from jortsc.parser.ast_nodes import (
|
||||
Function, TypedVar, Identifier, Import, ReturnType
|
||||
Function, TypedVar, Identifier, Import, ReturnType, String, Number,
|
||||
FunctionCall
|
||||
)
|
||||
|
||||
|
||||
|
@ -18,7 +19,8 @@ class Reader:
|
|||
self.cur = 0
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Reader cur={self.cur} cur_tok={self.peek()}>'
|
||||
return (f'<Reader cur={self.cur} tot={len(self.tokens)} '
|
||||
f'cur_tok={self.peek()}>')
|
||||
|
||||
def peek(self) -> Optional[Token]:
|
||||
"""Peek at the current token."""
|
||||
|
@ -168,6 +170,34 @@ def read_reserved(token: Token, reader: Reader):
|
|||
return handler(reader)
|
||||
|
||||
|
||||
def read_value(token: Token, _reader: Reader):
|
||||
"""Read a given value"""
|
||||
if token.type_ == TokenType.string:
|
||||
return String(token.value)
|
||||
elif token.type_ == TokenType.number:
|
||||
return Number(token.value)
|
||||
|
||||
|
||||
def read_statement(token: Token, reader: Reader):
|
||||
"""Read a statement"""
|
||||
# token is an identifier, so first check for a function call
|
||||
|
||||
# TODO: handle more things than a function call
|
||||
call_fn_name = token.value
|
||||
token = reader.expect_val('(')
|
||||
res = []
|
||||
|
||||
while True:
|
||||
token = reader.next_safe()
|
||||
|
||||
if token.value == ')':
|
||||
break
|
||||
|
||||
res.append(read_value(token, reader))
|
||||
|
||||
return FunctionCall(call_fn_name, res)
|
||||
|
||||
|
||||
def read_start(reader: Reader):
|
||||
"""Read the start of a program."""
|
||||
print('reader', reader)
|
||||
|
@ -181,8 +211,6 @@ def read_start(reader: Reader):
|
|||
ast = []
|
||||
res = []
|
||||
|
||||
print('cur', token)
|
||||
|
||||
# handle blocks
|
||||
if token.value == '{':
|
||||
# next can be a whitespace, or a }
|
||||
|
@ -193,10 +221,12 @@ def read_start(reader: Reader):
|
|||
if token.type_ == TokenType.whitespace:
|
||||
# keep going on reading
|
||||
while True:
|
||||
token = reader.next()
|
||||
print(token)
|
||||
token = reader.peek()
|
||||
print('block append', token)
|
||||
|
||||
if token.value == '}':
|
||||
print('block end')
|
||||
reader.next()
|
||||
break
|
||||
|
||||
res.extend(read_start(reader))
|
||||
|
@ -211,7 +241,9 @@ def read_start(reader: Reader):
|
|||
return []
|
||||
|
||||
elif token.type_ == TokenType.identifier:
|
||||
res = [Identifier(token.value)]
|
||||
res = read_statement(token, reader)
|
||||
else:
|
||||
res = read_value(token, reader)
|
||||
|
||||
ast.append(res)
|
||||
return ast
|
||||
|
@ -228,13 +260,9 @@ def read_loop(reader: Reader):
|
|||
if ast is None:
|
||||
break
|
||||
|
||||
try:
|
||||
inner = ast[0]
|
||||
except IndexError:
|
||||
inner = None
|
||||
# TODO: better ast cleanup
|
||||
|
||||
if ast and not inner:
|
||||
final_ast.append(ast)
|
||||
final_ast.append(ast)
|
||||
|
||||
return final_ast
|
||||
|
||||
|
|
Loading…
Reference in a new issue