Initial commit - fix problems & refactor code
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
from core.environment import IGNORE
|
||||
|
||||
def cleanString(s: str, ignore: str = IGNORE) -> str:
|
||||
s = s.lstrip(ignore)
|
||||
while s and s[0] == ';':
|
||||
line_end: int = s.find('\n')
|
||||
if line_end < 0:
|
||||
return ''
|
||||
s = s[line_end:].lstrip(ignore)
|
||||
return s
|
||||
@@ -0,0 +1,9 @@
|
||||
from core.environment import IGNORE, MEANINGFUL
|
||||
import re
|
||||
|
||||
def findPrefix(s: str, separators: str = IGNORE + MEANINGFUL) -> str:
|
||||
pattern = rf'^[^{separators}]*'
|
||||
match = re.match(pattern, s)
|
||||
if match:
|
||||
return match.group(0)
|
||||
return ''
|
||||
@@ -0,0 +1,52 @@
|
||||
from core.parser.clean_string import cleanString
|
||||
from core.parser.parse_token import parseToken
|
||||
from core.parser.find_prefix import findPrefix
|
||||
|
||||
from core.primitives.list import (
|
||||
cons,
|
||||
NIL
|
||||
)
|
||||
from core.exceptions import (
|
||||
syntaxError,
|
||||
runtimeError
|
||||
)
|
||||
|
||||
from core.tokens import SpecialForm
|
||||
|
||||
def parseExpression(s: str) -> tuple:
|
||||
s = cleanString(s)
|
||||
if not s:
|
||||
return NIL, s
|
||||
match s[0]:
|
||||
case '"': # string
|
||||
matching = s.find('"', 1)
|
||||
if matching < 0:
|
||||
raise syntaxError(f'the closing " is missing: {s}')
|
||||
return s[1:matching], s[matching + 1:]
|
||||
case '(': # list
|
||||
cache = s # saving initial view for Error illustration
|
||||
s = s[1:]
|
||||
arr: list = []
|
||||
while s and s[0] != ')':
|
||||
elem, s = parseExpression(s)
|
||||
arr.append(elem)
|
||||
s = cleanString(s)
|
||||
if not s:
|
||||
raise syntaxError(f'the closing ) is missing: {cache}')
|
||||
result = NIL
|
||||
for elem in reversed(arr):
|
||||
result = cons(elem, result)
|
||||
return result, s[1:]
|
||||
case ')':
|
||||
raise syntaxError(f'extra closing bracket: {s}') # TODO debug
|
||||
case "'":
|
||||
try:
|
||||
v, rem = parseExpression(s[1:])
|
||||
except Exception as e:
|
||||
raise runtimeError(f'invalid quote: {s}') from e
|
||||
if v is None:
|
||||
raise syntaxError(f'quote of nothing: {s}')
|
||||
return cons(SpecialForm.QUOTE, cons(v, NIL)), rem
|
||||
case _: # maybe we can find token
|
||||
first = findPrefix(s)
|
||||
return parseToken(first) if first else NIL, s[len(first):]
|
||||
@@ -0,0 +1,22 @@
|
||||
from core.tokens import (
|
||||
SpecialForm,
|
||||
BinaryOperator,
|
||||
BinaryPredicate
|
||||
)
|
||||
from core.primitives.symbol import symbol
|
||||
|
||||
def parseToken(token: str):
|
||||
for en in [SpecialForm, BinaryOperator, BinaryPredicate]:
|
||||
if token in en:
|
||||
return en(token)
|
||||
if token in ['true', 'false']:
|
||||
return token == 'true'
|
||||
try:
|
||||
return int(token)
|
||||
except ValueError:
|
||||
if token == 'inf':
|
||||
return symbol(token)
|
||||
try:
|
||||
return float(token)
|
||||
except ValueError:
|
||||
return symbol(token)
|
||||
Reference in New Issue
Block a user