Added some more builtins and polished inheritance structure

This commit is contained in:
nocturn9x 2020-08-05 16:25:35 +02:00
parent 496419fc26
commit 0e6f4556db
4 changed files with 115 additions and 65 deletions

View File

@ -5,10 +5,10 @@ from .types.japlclass import JAPLClass
from .types.instance import JAPLInstance
from .meta.environment import Environment
from .meta.tokentype import TokenType
from .types.native import Clock, Type, JAPLFunction, Truthy, Stringify
from .meta.exceptions import JAPLError, BreakException, ReturnException
from .types.native import Clock, Type, JAPLFunction, Truthy, Stringify, PrintFunction, IsInstance, IsSubclass, IsSuperclass
from .meta.expression import Expression, Variable, Literal, Logical, Binary, Unary, Grouping, Assignment, Call, Get, Set
from .meta.statement import Statement, Print, StatementExpr, If, While, Del, Break, Return, Var, Block, Function, Class
from .meta.statement import Statement, StatementExpr, If, While, Del, Break, Return, Var, Block, Function, Class
class Interpreter(Expression.Visitor, Statement.Visitor):
@ -32,6 +32,10 @@ class Interpreter(Expression.Visitor, Statement.Visitor):
self.globals.define("type", Type())
self.globals.define("truthy", Truthy())
self.globals.define("stringify", Stringify())
self.globals.define("print", PrintFunction())
self.globals.define("isinstance", IsInstance())
self.globals.define("issuperclass", IsSuperclass())
self.globals.define("issubclass", IsSubclass())
def number_operand(self, op, operand):
"""
@ -130,16 +134,6 @@ class Interpreter(Expression.Visitor, Statement.Visitor):
self.compatible_operands(expr.operator, left, right)
return self.OPS[expr.operator.kind](left, right)
def visit_print(self, stmt: Print):
"""
Visits the print statement node in the AST and
evaluates its expression before printing it to
stdout
"""
val = self.eval(stmt.expression)
print(val)
def visit_statement_expr(self, stmt: StatementExpr):
"""
Visits an expression statement and evaluates it

View File

@ -16,9 +16,6 @@ class Statement(object):
class Visitor(ABC):
"""Wrapper to implement the Visitor Pattern"""
@abstractmethod
def visit_print(self, visitor):
raise NotImplementedError
@abstractmethod
def visit_statement_expr(self, visitor):
@ -60,17 +57,6 @@ class Statement(object):
def visit_class(self, visitor):
raise NotImplementedError
@dataclass
class Print(Statement):
"""
The print statement
"""
expression: Expression
def accept(self, visitor):
visitor.visit_print(self)
@dataclass
class StatementExpr(Statement):

View File

@ -3,7 +3,7 @@ from .meta.tokentype import TokenType
from .meta.tokenobject import Token
from typing import List, Union
from .meta.expression import Variable, Assignment, Logical, Call, Binary, Unary, Literal, Grouping, Expression, Get, Set, This, Super
from .meta.statement import Print, StatementExpr, Var, Del, Block, If, While, Break, Function, Return, Class
from .meta.statement import StatementExpr, Var, Del, Block, If, While, Break, Function, Return, Class
class Parser(object):
@ -42,7 +42,7 @@ class Parser(object):
else:
token_type = self.peek().kind
if token_type in (
TokenType.IF, TokenType.CLASS, TokenType.VAR, TokenType.FOR, TokenType.WHILE, TokenType.PRINT,
TokenType.IF, TokenType.CLASS, TokenType.VAR, TokenType.FOR, TokenType.WHILE,
TokenType.RETURN, TokenType.FUN
):
return
@ -264,13 +264,6 @@ class Parser(object):
self.current += 1
return self.previous()
def print_statement(self):
"""Returns a Print AST node"""
value = self.expression()
self.consume(TokenType.SEMICOLON, "Missing semicolon after print statement")
return Print(value)
def del_statement(self):
"""Returns a del AST node"""
@ -365,8 +358,6 @@ class Parser(object):
if self.match(TokenType.IF):
return self.if_statement()
elif self.match(TokenType.PRINT):
return self.print_statement()
elif self.match(TokenType.RETURN):
return self.return_statement()
elif self.match(TokenType.FOR):

View File

@ -2,6 +2,8 @@ from .callable import Callable
import time
from ..meta.environment import Environment
from ..meta.exceptions import ReturnException
from .instance import JAPLInstance
from .japlclass import JAPLClass
class Clock(Callable):
@ -34,6 +36,111 @@ class Type(Callable):
return f"<built-in function type>"
class Truthy(Callable):
"""JAPL's wrapper around bool"""
def __init__(self, *_):
"""Object constructor"""
self.arity = 1
def call(self, _, obj):
return bool(obj[0])
def __repr__(self):
return f"<built-in function truthy>"
class Stringify(Callable):
"""JAPL's wrapper around str()"""
def __init__(self, *_):
"""Object constructor"""
self.arity = 1
def call(self, _, obj):
return str(obj[0])
def __repr__(self):
return f"<built-in function stringify>"
class PrintFunction(Callable):
"""The print function"""
def __init__(self, *_):
"""Object constructor"""
self.arity = 1
def call(self, _, *args):
print(*args[0])
def __repr__(self):
return "<built-in function print>"
class IsInstance(Callable):
"""The isinstance function"""
def __init__(self, *_):
"""Object constructor"""
self.arity = 2
def call(self, _, args):
instance, klass = args
if not isinstance(instance, JAPLInstance):
return False
elif not isinstance(klass, JAPLClass):
return False
return instance.klass == klass
def __repr__(self):
return "<built-in function isinstance>"
class IsSubclass(Callable):
"""The isinstance function"""
def __init__(self, *_):
"""Object constructor"""
self.arity = 2
def call(self, _, args):
first, second = args
if not isinstance(first, JAPLClass):
return False
elif not isinstance(second, JAPLClass):
return False
return first.superclass == second
def __repr__(self):
return "<built-in function issubclass>"
class IsSuperclass(Callable):
"""The isinstance function"""
def __init__(self, *_):
"""Object constructor"""
self.arity = 2
def call(self, _, args):
first, second = args
if not isinstance(first, JAPLClass):
return False
elif not isinstance(second, JAPLClass):
return False
return second.superclass == first
def __repr__(self):
return "<built-in function issuperclass>"
class JAPLFunction(Callable):
"""A generic wrapper for user-defined functions"""
@ -66,31 +173,3 @@ class JAPLFunction(Callable):
def __repr__(self):
return self._repr
class Truthy(Callable):
"""JAPL's wrapper around bool"""
def __init__(self, *_):
"""Object constructor"""
self.arity = 1
def call(self, _, obj):
return bool(obj[0])
def __repr__(self):
return f"<built-in function truthy>"
class Stringify(Callable):
"""JAPL's wrapper around str()"""
def __init__(self, *_):
"""Object constructor"""
self.arity = 1
def call(self, _, obj):
return str(obj[0])
def __repr__(self):
return f"<built-in function stringify>"