implement boolean
This commit is contained in:
@ -7,5 +7,42 @@ def pass:
|
|||||||
object inttrait:
|
object inttrait:
|
||||||
def add(other):
|
def add(other):
|
||||||
self $int_add(other)
|
self $int_add(other)
|
||||||
|
|
||||||
|
# Project: Sugar
|
||||||
|
def sub(other):
|
||||||
|
self $int_sub(other)
|
||||||
|
def mul(other):
|
||||||
|
self $int_mul(other)
|
||||||
|
def div(other):
|
||||||
|
self $int_div(other)
|
||||||
|
def mod(other):
|
||||||
|
self $int_mod(other)
|
||||||
|
def inc:
|
||||||
|
self $int_inc
|
||||||
|
|
||||||
|
# Project: Boolean
|
||||||
def eq(other):
|
def eq(other):
|
||||||
self $int_eq(other)
|
self $int_eq(other)
|
||||||
|
def leq(other):
|
||||||
|
self $int_leq(other)
|
||||||
|
def geq(other):
|
||||||
|
self $int_geq(other)
|
||||||
|
def greater(other):
|
||||||
|
self $int_greater(other)
|
||||||
|
def less(other):
|
||||||
|
self $int_less(other)
|
||||||
|
|
||||||
|
def tobool:
|
||||||
|
self $int_tobool
|
||||||
|
|
||||||
|
# Project: Boolean
|
||||||
|
object booltrait:
|
||||||
|
def and(other):
|
||||||
|
self $bool_and(other)
|
||||||
|
def or(other):
|
||||||
|
self $bool_or(other)
|
||||||
|
def not:
|
||||||
|
self $bool_not
|
||||||
|
|
||||||
|
def toint:
|
||||||
|
self $bool_toint
|
||||||
|
@ -64,6 +64,9 @@ class Interpreter(object):
|
|||||||
elif opcode == compile.INT_LITERAL:
|
elif opcode == compile.INT_LITERAL:
|
||||||
w_value = self.space.newint(oparg)
|
w_value = self.space.newint(oparg)
|
||||||
stack.append(w_value)
|
stack.append(w_value)
|
||||||
|
elif opcode == compile.BOOL_LITERAL: # Project: Boolean
|
||||||
|
w_value = self.space.newbool(oparg) # oparg is 1 or 0
|
||||||
|
stack.append(w_value)
|
||||||
elif opcode == compile.MAKE_FUNCTION:
|
elif opcode == compile.MAKE_FUNCTION:
|
||||||
bc = bytecode.subbytecodes[oparg]
|
bc = bytecode.subbytecodes[oparg]
|
||||||
w_method = self.space.definemethod(name=bc.name, code=bc, w_target=w_context)
|
w_method = self.space.definemethod(name=bc.name, code=bc, w_target=w_context)
|
||||||
|
@ -109,23 +109,24 @@ import simpleast
|
|||||||
|
|
||||||
# ---------- bytecodes ----------
|
# ---------- bytecodes ----------
|
||||||
|
|
||||||
INT_LITERAL = 2 # integer value
|
BOOL_LITERAL = 1 # 1 or 0 # Project: Boolean
|
||||||
ASSIGNMENT = 4 # index of attrname
|
INT_LITERAL = 2 # integer value
|
||||||
METHOD_LOOKUP = 5 # index of method name
|
ASSIGNMENT = 4 # index of attrname
|
||||||
METHOD_CALL = 6 # number of arguments
|
METHOD_LOOKUP = 5 # index of method name
|
||||||
PRIMITIVE_METHOD_CALL = 7 # number of the primitive
|
METHOD_CALL = 6 # number of arguments
|
||||||
MAKE_FUNCTION = 8 # bytecode literal index
|
PRIMITIVE_METHOD_CALL = 7 # number of the primitive
|
||||||
MAKE_OBJECT = 9 # index of object name
|
MAKE_FUNCTION = 8 # bytecode literal index
|
||||||
ASSIGNMENT_APPEND_PARENT = 10 # index of parentname
|
MAKE_OBJECT = 9 # index of object name
|
||||||
MAKE_OBJECT_CALL = 11 # bytecode literal index
|
ASSIGNMENT_APPEND_PARENT = 10 # index of parentname
|
||||||
JUMP_IF_FALSE = 12 # offset
|
MAKE_OBJECT_CALL = 11 # bytecode literal index
|
||||||
JUMP = 13 # offset
|
JUMP_IF_FALSE = 12 # offset
|
||||||
GET_LOCAL = 15 # index of attrname (optimization)
|
JUMP = 13 # offset
|
||||||
SET_LOCAL = 16 # index of attrname (optimization)
|
GET_LOCAL = 15 # index of attrname (optimization)
|
||||||
|
SET_LOCAL = 16 # index of attrname (optimization)
|
||||||
|
|
||||||
IMPLICIT_SELF = 32 # (no argument)
|
IMPLICIT_SELF = 32 # (no argument)
|
||||||
POP = 33 # (no argument)
|
POP = 33 # (no argument)
|
||||||
DUP = 34 # (no argument)
|
DUP = 34 # (no argument)
|
||||||
|
|
||||||
opcode_names = [None] * 256
|
opcode_names = [None] * 256
|
||||||
for key, value in list(globals().items()):
|
for key, value in list(globals().items()):
|
||||||
@ -133,11 +134,11 @@ for key, value in list(globals().items()):
|
|||||||
opcode_names[value] = key
|
opcode_names[value] = key
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def hasarg(opcode):
|
def hasarg(opcode):
|
||||||
""" Helper function to determine whether an opcode has an argument."""
|
""" Helper function to determine whether an opcode has an argument."""
|
||||||
return opcode < 32
|
return opcode < 32
|
||||||
|
|
||||||
|
|
||||||
def isjump(opcode):
|
def isjump(opcode):
|
||||||
""" Helper function to determine whether an opcode is a jump."""
|
""" Helper function to determine whether an opcode is a jump."""
|
||||||
return opcode == JUMP_IF_FALSE or opcode == JUMP
|
return opcode == JUMP_IF_FALSE or opcode == JUMP
|
||||||
@ -188,6 +189,7 @@ def compile(ast, argumentnames=[], name=None):
|
|||||||
|
|
||||||
|
|
||||||
stack_effects = {
|
stack_effects = {
|
||||||
|
BOOL_LITERAL: 1, # Project: Boolean
|
||||||
INT_LITERAL: 1,
|
INT_LITERAL: 1,
|
||||||
ASSIGNMENT: -1,
|
ASSIGNMENT: -1,
|
||||||
METHOD_LOOKUP: 1,
|
METHOD_LOOKUP: 1,
|
||||||
@ -219,10 +221,10 @@ class Compiler(object):
|
|||||||
for name, index in list(self.symbols.items()):
|
for name, index in list(self.symbols.items()):
|
||||||
symbols[index] = name
|
symbols[index] = name
|
||||||
result = Bytecode(''.join(self.code),
|
result = Bytecode(''.join(self.code),
|
||||||
funcname,
|
funcname,
|
||||||
symbols,
|
symbols,
|
||||||
self.subbytecodes,
|
self.subbytecodes,
|
||||||
numargs, self.max_stackdepth)
|
numargs, self.max_stackdepth)
|
||||||
assert self.stackdepth == 1
|
assert self.stackdepth == 1
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -257,10 +259,10 @@ class Compiler(object):
|
|||||||
return len(self.code)
|
return len(self.code)
|
||||||
|
|
||||||
def set_target_position(self, oldposition, newtarget):
|
def set_target_position(self, oldposition, newtarget):
|
||||||
offset = newtarget - (oldposition+5)
|
offset = newtarget - (oldposition + 5)
|
||||||
i = 0
|
i = 0
|
||||||
for c in self.encode4(offset):
|
for c in self.encode4(offset):
|
||||||
self.code[oldposition+1+i] = c
|
self.code[oldposition + 1 + i] = c
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
def encode4(self, value):
|
def encode4(self, value):
|
||||||
@ -274,13 +276,16 @@ class Compiler(object):
|
|||||||
self.symbols[symbol] = len(self.symbols)
|
self.symbols[symbol] = len(self.symbols)
|
||||||
return self.symbols[symbol]
|
return self.symbols[symbol]
|
||||||
|
|
||||||
|
|
||||||
def compile(self, ast, needsresult=True):
|
def compile(self, ast, needsresult=True):
|
||||||
return getattr(self, "compile_" + ast.__class__.__name__)(ast, needsresult)
|
return getattr(self, "compile_" + ast.__class__.__name__)(ast, needsresult)
|
||||||
|
|
||||||
def compile_IntLiteral(self, astnode, needsresult):
|
def compile_IntLiteral(self, astnode, needsresult):
|
||||||
self.emit(INT_LITERAL, astnode.value)
|
self.emit(INT_LITERAL, astnode.value)
|
||||||
|
|
||||||
|
# Project: Boolean
|
||||||
|
def compile_BooleanLiteral(self, astnode, needsresult):
|
||||||
|
self.emit(BOOL_LITERAL, astnode.value)
|
||||||
|
|
||||||
def compile_ImplicitSelf(self, astnode, needsresult):
|
def compile_ImplicitSelf(self, astnode, needsresult):
|
||||||
self.emit(IMPLICIT_SELF)
|
self.emit(IMPLICIT_SELF)
|
||||||
|
|
||||||
@ -318,7 +323,7 @@ class Compiler(object):
|
|||||||
expected_args = primitives.get_number_of_arguments_of_primitive(index)
|
expected_args = primitives.get_number_of_arguments_of_primitive(index)
|
||||||
if not (len(astnode.arguments) == expected_args):
|
if not (len(astnode.arguments) == expected_args):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"Expected {ex} arguments, received {re}.".format(ex=expected_args, re=len(astnode.arguments)))
|
"Expected {ex} arguments, received {re}.".format(ex=expected_args, re=len(astnode.arguments)))
|
||||||
self.compile(astnode.receiver)
|
self.compile(astnode.receiver)
|
||||||
for arg in astnode.arguments:
|
for arg in astnode.arguments:
|
||||||
self.compile(arg)
|
self.compile(arg)
|
||||||
|
@ -74,16 +74,17 @@ class W_NormalObject(AbstractObject):
|
|||||||
|
|
||||||
|
|
||||||
class W_Integer(AbstractObject):
|
class W_Integer(AbstractObject):
|
||||||
def __init__(self, value, space=None):
|
def __init__(self, value, space=None, trait="inttrait"):
|
||||||
self.value = value
|
self.value = int(value)
|
||||||
self.space = space
|
self.space = space
|
||||||
|
self.__trait = trait # used this to extend from W_Integer
|
||||||
|
|
||||||
def getparents(self):
|
def getparents(self):
|
||||||
if self.space is None:
|
if self.space is None:
|
||||||
return [] # for tests
|
return [] # for tests
|
||||||
inttrait = self.space.getbuiltin('inttrait')
|
trait = self.space.getbuiltin(self.__trait)
|
||||||
assert inttrait is not None, 'O_o bogus state'
|
assert trait is not None, 'O_o bogus state'
|
||||||
return [inttrait]
|
return [trait]
|
||||||
|
|
||||||
def hasslot(self, name):
|
def hasslot(self, name):
|
||||||
return False
|
return False
|
||||||
@ -97,6 +98,12 @@ class W_Integer(AbstractObject):
|
|||||||
return self.value != 0
|
return self.value != 0
|
||||||
|
|
||||||
|
|
||||||
|
# Project: Boolean
|
||||||
|
class W_Boolean(W_Integer): # don't know if extending is good idea
|
||||||
|
def __init__(self, value, space=None):
|
||||||
|
super().__init__(int(value), space=space, trait="booltrait")
|
||||||
|
|
||||||
|
|
||||||
class W_Method(W_NormalObject):
|
class W_Method(W_NormalObject):
|
||||||
|
|
||||||
def __init__(self, code, *args, **kwargs):
|
def __init__(self, code, *args, **kwargs):
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from objmodel import W_Integer
|
from objmodel import W_Integer, W_Boolean
|
||||||
from objmodel import W_Method
|
from objmodel import W_Method
|
||||||
from objmodel import W_NormalObject
|
from objmodel import W_NormalObject
|
||||||
|
|
||||||
@ -49,6 +49,10 @@ class ObjectSpace(object):
|
|||||||
def newint(self, value):
|
def newint(self, value):
|
||||||
return W_Integer(value, space=self)
|
return W_Integer(value, space=self)
|
||||||
|
|
||||||
|
# Project: Boolean
|
||||||
|
def newbool(self, value):
|
||||||
|
return W_Boolean(value, space=self)
|
||||||
|
|
||||||
def definemethod(self, name, code, w_target):
|
def definemethod(self, name, code, w_target):
|
||||||
w_meth = W_Method(code, name=name,
|
w_meth = W_Method(code, name=name,
|
||||||
slots={'__parent__': w_target},
|
slots={'__parent__': w_target},
|
||||||
|
@ -3,25 +3,32 @@ all_primitives = []
|
|||||||
primitive_number_of_arguments = []
|
primitive_number_of_arguments = []
|
||||||
|
|
||||||
|
|
||||||
def primitive(name, unwrap_spec, wrap_spec):
|
def primitive(name, unwrap_spec, wrap_spec): # decorator arguments
|
||||||
assert '$' + name not in registry, '${name} already defined'.format(name=name)
|
assert '$' + name not in registry, '${name} already defined'.format(name=name)
|
||||||
primitive_number_of_arguments.append(len(unwrap_spec) - 1) # first argument is the receiver
|
primitive_number_of_arguments.append(len(unwrap_spec) - 1) # first argument is the receiver
|
||||||
|
|
||||||
def expose(func):
|
def expose(func): # decorator
|
||||||
def unwrapper(w_receiver, args_w, space):
|
def unwrapper(w_receiver, args_w, space):
|
||||||
args = [w_receiver] + args_w
|
args = [w_receiver] + args_w
|
||||||
if len(args) != len(unwrap_spec):
|
if len(args) != len(unwrap_spec): # check that call args match primitive args
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"Expected {ex} arguments, received {re}.".format(ex=len(unwrap_spec), re=len(args)))
|
"Expected {ex} arguments, received {re}.".format(ex=len(unwrap_spec), re=len(args)))
|
||||||
|
|
||||||
unwrapped_args = ()
|
unwrapped_args = ()
|
||||||
for t, arg in zip(unwrap_spec, args):
|
for t, arg in zip(unwrap_spec, args): # unpack values from simple-objects
|
||||||
if t is int:
|
if t is int:
|
||||||
unwrapped_args += (arg.value,)
|
unwrapped_args += (arg.value,)
|
||||||
|
elif t is bool: # Project: Boolean
|
||||||
|
unwrapped_args += (bool(arg.value),) # isn't necessary because "1 or 0" is valid
|
||||||
else:
|
else:
|
||||||
unwrapped_args += (arg,)
|
unwrapped_args += (arg,)
|
||||||
result = func(*unwrapped_args)
|
|
||||||
if wrap_spec is int:
|
result = func(*unwrapped_args) # actual call
|
||||||
|
|
||||||
|
if wrap_spec is int: # wrap the result
|
||||||
return space.newint(result)
|
return space.newint(result)
|
||||||
|
elif wrap_spec is bool: # Project: Boolean
|
||||||
|
return space.newbool(result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
unwrapper.__qualname__ = name
|
unwrapper.__qualname__ = name
|
||||||
@ -45,12 +52,7 @@ def simple_int_add(a, b):
|
|||||||
return a + b
|
return a + b
|
||||||
|
|
||||||
|
|
||||||
@primitive('int_eq', [int, int], int)
|
# Project: Sugar
|
||||||
def simple_int_eq(a, b):
|
|
||||||
return a == b
|
|
||||||
|
|
||||||
|
|
||||||
# Syntactic Sugar Primitives
|
|
||||||
@primitive("int_sub", [int, int], int)
|
@primitive("int_sub", [int, int], int)
|
||||||
def simple_int_subtract(a, b):
|
def simple_int_subtract(a, b):
|
||||||
return a - b
|
return a - b
|
||||||
@ -74,3 +76,54 @@ def simple_int_modulo(a, b):
|
|||||||
@primitive("int_inc", [int], int)
|
@primitive("int_inc", [int], int)
|
||||||
def simple_int_increment(a):
|
def simple_int_increment(a):
|
||||||
return a + 1
|
return a + 1
|
||||||
|
|
||||||
|
|
||||||
|
# Project: Boolean
|
||||||
|
@primitive("bool_and", [bool, bool], bool)
|
||||||
|
def simple_bool_and(a, b):
|
||||||
|
return a and b
|
||||||
|
|
||||||
|
|
||||||
|
@primitive("bool_or", [bool, bool], bool)
|
||||||
|
def simple_bool_or(a, b):
|
||||||
|
return a or b
|
||||||
|
|
||||||
|
|
||||||
|
@primitive("bool_not", [bool], bool)
|
||||||
|
def simple_bool_not(a):
|
||||||
|
return not a
|
||||||
|
|
||||||
|
|
||||||
|
@primitive("int_eq", [int, int], bool)
|
||||||
|
def simple_int_eq(a, b):
|
||||||
|
return a == b
|
||||||
|
|
||||||
|
|
||||||
|
@primitive("int_leq", [int, int], bool)
|
||||||
|
def simple_int_leq(a, b):
|
||||||
|
return a <= b
|
||||||
|
|
||||||
|
|
||||||
|
@primitive("int_geq", [int, int], bool)
|
||||||
|
def simple_int_geq(a, b):
|
||||||
|
return a >= b
|
||||||
|
|
||||||
|
|
||||||
|
@primitive("int_greater", [int, int], bool)
|
||||||
|
def simple_int_greater(a, b):
|
||||||
|
return a > b
|
||||||
|
|
||||||
|
|
||||||
|
@primitive("int_less", [int, int], bool)
|
||||||
|
def simple_int_less(a, b):
|
||||||
|
return a < b
|
||||||
|
|
||||||
|
|
||||||
|
@primitive("int_tobool", [int], bool)
|
||||||
|
def simple_int_tobool(a):
|
||||||
|
return a
|
||||||
|
|
||||||
|
|
||||||
|
@primitive("bool_toint", [bool], int)
|
||||||
|
def simple_bool_toint(a):
|
||||||
|
return a
|
||||||
|
@ -93,8 +93,9 @@ class IntLiteral(Expression):
|
|||||||
self.value = int(value)
|
self.value = int(value)
|
||||||
|
|
||||||
|
|
||||||
|
# Project: String
|
||||||
class StringLiteral(Expression):
|
class StringLiteral(Expression):
|
||||||
""" An string literal (like "hello world") """
|
""" A string literal (like "hello world") """
|
||||||
|
|
||||||
attrs = ["value"]
|
attrs = ["value"]
|
||||||
|
|
||||||
@ -102,6 +103,16 @@ class StringLiteral(Expression):
|
|||||||
self.value = str(value)
|
self.value = str(value)
|
||||||
|
|
||||||
|
|
||||||
|
# Project: Boolean
|
||||||
|
class BooleanLiteral(Expression):
|
||||||
|
""" A boolean literal (like "false") """
|
||||||
|
|
||||||
|
attrs = ["value"]
|
||||||
|
|
||||||
|
def __init__(self, value):
|
||||||
|
self.value = value == "true"
|
||||||
|
|
||||||
|
|
||||||
class MethodCall(Expression):
|
class MethodCall(Expression):
|
||||||
""" A call to a method with name 'methodname' on 'receiver' with
|
""" A call to a method with name 'methodname' on 'receiver' with
|
||||||
'arguments' (which is a list of expression ASTs).
|
'arguments' (which is a list of expression ASTs).
|
||||||
|
@ -130,7 +130,6 @@ def make_single_string(delim):
|
|||||||
# Literals
|
# Literals
|
||||||
|
|
||||||
Number = r'(([+-])?[1-9][0-9]*)|0'
|
Number = r'(([+-])?[1-9][0-9]*)|0'
|
||||||
String = group(make_single_string(r"\'"), make_single_string(r'\"'))
|
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# Ignored
|
# Ignored
|
||||||
@ -159,7 +158,13 @@ OpenBracket = r'[\[\(\{]'
|
|||||||
CloseBracket = r'[\]\)\}]'
|
CloseBracket = r'[\]\)\}]'
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# Syntactic Sugar Operators
|
# Project: Boolean, String
|
||||||
|
|
||||||
|
Boolean = group(r'true', r'false')
|
||||||
|
String = group(make_single_string(r"\'"), make_single_string(r'\"'))
|
||||||
|
|
||||||
|
# ____________________________________________________________
|
||||||
|
# Project: Sugar
|
||||||
|
|
||||||
Plus = r'\+'
|
Plus = r'\+'
|
||||||
Minus = r'-'
|
Minus = r'-'
|
||||||
@ -178,8 +183,9 @@ Def = r'def'
|
|||||||
Object = r'object'
|
Object = r'object'
|
||||||
|
|
||||||
tokens = ["If", "Else", "While", "Def", "Object", "Number", "String", "Ignore",
|
tokens = ["If", "Else", "While", "Def", "Object", "Number", "String", "Ignore",
|
||||||
|
"Boolean", # Project: Boolean
|
||||||
"NewlineAndWhitespace", "OpenBracket", "CloseBracket", "Comma", "Assign", "Colon",
|
"NewlineAndWhitespace", "OpenBracket", "CloseBracket", "Comma", "Assign", "Colon",
|
||||||
"Increment", "Plus", "Minus", "Multiply", "Divide", "Modulo", # Sugar
|
"Increment", "Plus", "Minus", "Multiply", "Divide", "Modulo", # Project: Sugar
|
||||||
"Name", "PrimitiveName"]
|
"Name", "PrimitiveName"]
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ from simplelexer import lex
|
|||||||
import simpleast
|
import simpleast
|
||||||
|
|
||||||
pg = ParserGenerator(["If", "Else", "While", "Def", "Object", "Number",
|
pg = ParserGenerator(["If", "Else", "While", "Def", "Object", "Number",
|
||||||
|
"Boolean", # New Types
|
||||||
"String", "Name", "Indent", "Dedent", "Newline", "OpenBracket",
|
"String", "Name", "Indent", "Dedent", "Newline", "OpenBracket",
|
||||||
"CloseBracket", "Comma", "Assign", "Colon",
|
"CloseBracket", "Comma", "Assign", "Colon",
|
||||||
"Increment", "Plus", "Minus", "Multiply", "Divide", "Modulo", # Sugar
|
"Increment", "Plus", "Minus", "Multiply", "Divide", "Modulo", # Sugar
|
||||||
@ -154,7 +155,7 @@ def expression(expr):
|
|||||||
return expr[0]
|
return expr[0]
|
||||||
|
|
||||||
|
|
||||||
# Syntactic Sugar: Plus, Minus, Multiply, Divide, Modulo, Increment
|
# Project: Sugar
|
||||||
@pg.production("expression : expression Plus expression")
|
@pg.production("expression : expression Plus expression")
|
||||||
@pg.production("expression : expression Minus expression")
|
@pg.production("expression : expression Minus expression")
|
||||||
@pg.production("expression : expression Multiply expression")
|
@pg.production("expression : expression Multiply expression")
|
||||||
@ -197,9 +198,16 @@ def number_expression(stmt):
|
|||||||
return simpleast.IntLiteral(stmt[0].value)
|
return simpleast.IntLiteral(stmt[0].value)
|
||||||
|
|
||||||
|
|
||||||
|
# Project: String
|
||||||
@pg.production("basic_expression : String")
|
@pg.production("basic_expression : String")
|
||||||
def string_expression(stmt):
|
def string_expression(stmt):
|
||||||
return simpleast.StringLiteral(stmt[0].value)
|
return simpleast.StringLiteral(stmt[0].value[1:-1]) # cut off delimiters
|
||||||
|
|
||||||
|
|
||||||
|
# Project: Boolean
|
||||||
|
@pg.production("basic_expression : Boolean")
|
||||||
|
def boolean_expression(stmt):
|
||||||
|
return simpleast.BooleanLiteral(stmt[0].value)
|
||||||
|
|
||||||
|
|
||||||
@pg.production("basic_expression : implicitselfmethodcall")
|
@pg.production("basic_expression : implicitselfmethodcall")
|
||||||
|
@ -1,10 +1,24 @@
|
|||||||
import py
|
import py
|
||||||
|
from rply import Token
|
||||||
|
|
||||||
|
from simpleast import Program, ExprStatement, BooleanLiteral, Assignment, ImplicitSelf
|
||||||
|
from simplelexer import lex
|
||||||
from simpleparser import parse
|
from simpleparser import parse
|
||||||
from objmodel import W_NormalObject, W_Integer
|
from objmodel import W_NormalObject, W_Integer, W_Boolean
|
||||||
from interpreter import Interpreter
|
from interpreter import Interpreter
|
||||||
|
|
||||||
|
|
||||||
|
def test_basic_boolean_lexing():
|
||||||
|
assert lex("true")[0] == Token("Boolean", "true")
|
||||||
|
assert lex("false")[0] == Token("Boolean", "false")
|
||||||
|
assert lex("x = true")[:3] == [Token("Name", "x"), Token("Assign", "="), Token("Boolean", "true")]
|
||||||
|
|
||||||
|
|
||||||
|
def test_basic_boolean_parsing():
|
||||||
|
assert parse("false") == Program([ExprStatement(BooleanLiteral("false"))])
|
||||||
|
assert parse("x = false") == Program([Assignment(ImplicitSelf(), "x", BooleanLiteral("false"))])
|
||||||
|
|
||||||
|
|
||||||
def test_boolean_assignment():
|
def test_boolean_assignment():
|
||||||
ast = parse("""
|
ast = parse("""
|
||||||
x = true
|
x = true
|
||||||
@ -24,7 +38,7 @@ def test_boolean_operations():
|
|||||||
ast = parse("""
|
ast = parse("""
|
||||||
x = true and(false)
|
x = true and(false)
|
||||||
y = true or(false)
|
y = true or(false)
|
||||||
z = not(true)
|
z = true not
|
||||||
""")
|
""")
|
||||||
interpreter = Interpreter()
|
interpreter = Interpreter()
|
||||||
w_model = interpreter.make_module()
|
w_model = interpreter.make_module()
|
||||||
@ -55,7 +69,7 @@ y = 1 leq(2)
|
|||||||
|
|
||||||
def test_boolean_conversion():
|
def test_boolean_conversion():
|
||||||
ast = parse("""
|
ast = parse("""
|
||||||
x = 1 toboolean
|
x = 1 tobool
|
||||||
y = true toint
|
y = true toint
|
||||||
z = false toint
|
z = false toint
|
||||||
""")
|
""")
|
||||||
|
Reference in New Issue
Block a user