Initial commit - fix problems & refactor code

This commit is contained in:
2025-12-22 19:10:46 +03:00
commit ff36917cb5
39 changed files with 1499 additions and 0 deletions
View File
+10
View File
@@ -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
+9
View File
@@ -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 ''
+52
View File
@@ -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):]
+22
View File
@@ -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)