more syntactic sugar
This commit is contained in:
@ -9,6 +9,8 @@ def pass:
|
||||
object inttrait:
|
||||
def eq(other):
|
||||
self $int_eq(other)
|
||||
def noteq(other):
|
||||
self $int_eq(other) not
|
||||
|
||||
def leq(other):
|
||||
self $int_leq(other)
|
||||
@ -31,6 +33,8 @@ object inttrait:
|
||||
self $int_mod(other)
|
||||
def inc:
|
||||
self $int_inc
|
||||
def dec:
|
||||
self $int_dec
|
||||
|
||||
def tobool:
|
||||
self $int_tobool
|
||||
|
@ -33,7 +33,7 @@ class Interpreter(object):
|
||||
pc = 0
|
||||
stack = []
|
||||
code = bytecode.code
|
||||
print(disassemble(bytecode))
|
||||
# print(disassemble(bytecode))
|
||||
while pc < len(code):
|
||||
opcode = ord(code[pc]) # convert unicode to number
|
||||
pc += 1
|
||||
|
@ -27,7 +27,8 @@ class ObjectSpace(object):
|
||||
import os
|
||||
builtins = os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
'../builtins.simple')
|
||||
'..',
|
||||
'builtins.simple')
|
||||
with open(builtins, 'r') as f:
|
||||
return f.read()
|
||||
|
||||
|
@ -106,6 +106,11 @@ def simple_int_increment(a):
|
||||
return a + 1
|
||||
|
||||
|
||||
@primitive("int_dec", [int], int)
|
||||
def simple_int_decrement(a):
|
||||
return a - 1
|
||||
|
||||
|
||||
@primitive("int_tobool", [int], bool)
|
||||
def simple_int_tobool(a):
|
||||
return a
|
||||
|
@ -174,8 +174,25 @@ Minus = r'-'
|
||||
Multiply = r'\*'
|
||||
Divide = r'/'
|
||||
Increment = r'\+\+'
|
||||
Decrement = r'--'
|
||||
Modulo = r'%'
|
||||
|
||||
PlusInplace = r'\+='
|
||||
MinusInplace = r'-='
|
||||
MultiplyInplace = r'\*='
|
||||
DivideInplace = r'/='
|
||||
|
||||
Less = r'<'
|
||||
LessEqual = r'<='
|
||||
Greater = r'>'
|
||||
GreaterEqual = r'>='
|
||||
Equal = r'=='
|
||||
NotEqual = r'!='
|
||||
|
||||
And = r'&&'
|
||||
Or = r'\|\|'
|
||||
Not = r'!'
|
||||
|
||||
GC = r'gc'
|
||||
|
||||
# ____________________________________________________________
|
||||
@ -191,9 +208,13 @@ tokens = ["If", "Else", "While", "Def", "Object", "Ignore",
|
||||
"String", "Boolean", "Double",
|
||||
"Number", # after Double
|
||||
"GC",
|
||||
"NewlineAndWhitespace", "OpenBracket", "CloseBracket", "Comma", "Assign", "Colon",
|
||||
"NewlineAndWhitespace", "OpenBracket", "CloseBracket", "Comma", "Colon",
|
||||
"And", "Or", "LessEqual", "Less", "GreaterEqual", "Greater", "Equal", "NotEqual",
|
||||
"Decrement", "PlusInplace", "MinusInplace", "MultiplyInplace", "DivideInplace",
|
||||
"Increment", "Plus", "Minus", "Multiply", "Divide", "Modulo",
|
||||
"Name", "PrimitiveName"]
|
||||
"Assign", "Not",
|
||||
"Name", "PrimitiveName",
|
||||
]
|
||||
|
||||
|
||||
def make_lexer():
|
||||
|
@ -9,13 +9,23 @@ pg = ParserGenerator(["If", "Else", "While", "Def", "Object", "Number",
|
||||
"String", "Boolean", "Double",
|
||||
"GC",
|
||||
"Name", "Indent", "Dedent", "Newline", "OpenBracket",
|
||||
"CloseBracket", "Comma", "Assign", "Colon",
|
||||
"CloseBracket", "Comma", "Colon",
|
||||
"Increment", "Plus", "Minus", "Multiply", "Divide", "Modulo",
|
||||
"PrimitiveName", "EOF"],
|
||||
"Decrement", "PlusInplace", "MinusInplace", "MultiplyInplace", "DivideInplace",
|
||||
"Less", "LessEqual", "Greater", "GreaterEqual", "Equal", "NotEqual",
|
||||
"Assign",
|
||||
"And", "Or",
|
||||
"PrimitiveName", "EOF",
|
||||
"Not"],
|
||||
# Operator precedence for ambiguous rules, ascending
|
||||
precedence=[("left", ["Plus", "Minus"]),
|
||||
precedence=[("left", ["Or"]),
|
||||
("left", ["And"]),
|
||||
("left", ["Equal", "NotEqual"]),
|
||||
("left", ["Less", "LessEqual", "Greater", "GreaterEqual"]),
|
||||
("left", ["Plus", "Minus"]),
|
||||
("left", ["Multiply", "Divide", "Modulo"]),
|
||||
("left", ["Increment"])])
|
||||
("left", ["Not"]),
|
||||
("left", ["Increment", "Decrement"])])
|
||||
|
||||
|
||||
def build_methodcall(call, cls, receiver=None):
|
||||
@ -103,7 +113,6 @@ def objectstatement(obj):
|
||||
if len(obj) == 3:
|
||||
blk = obj[2]
|
||||
else:
|
||||
print(obj)
|
||||
parents = obj[2] # list of assignments (simpleast.Assignment)
|
||||
names = [p.attrname for p in parents]
|
||||
expressions = [p.expression for p in parents]
|
||||
@ -168,22 +177,76 @@ def expression(expr):
|
||||
@pg.production("expression : expression Multiply expression")
|
||||
@pg.production("expression : expression Divide expression")
|
||||
@pg.production("expression : expression Modulo expression")
|
||||
@pg.production("expression : expression Increment expression")
|
||||
@pg.production("expression : expression Increment")
|
||||
def sugar(expr):
|
||||
def sugar_binary_arithmetic(expr):
|
||||
op = {
|
||||
"Plus": "$int_add",
|
||||
"Minus": "$int_sub",
|
||||
"Multiply": "$int_mul",
|
||||
"Divide": "$int_div",
|
||||
"Modulo": "$int_mod",
|
||||
"Increment": "$int_inc"
|
||||
"Plus": "add",
|
||||
"Minus": "sub",
|
||||
"Multiply": "mul",
|
||||
"Divide": "div",
|
||||
"Modulo": "mod",
|
||||
}[expr[1].name]
|
||||
|
||||
if len(expr) == 2: # unary operator
|
||||
return build_methodcall([op, []], simpleast.PrimitiveMethodCall, expr[0]) # ([name, arg], class, receiver)
|
||||
return build_methodcall([op, [expr[2]]], simpleast.MethodCall, expr[0]) # ([name, arg], class, receiver)
|
||||
|
||||
return build_methodcall([op, [expr[2]]], simpleast.PrimitiveMethodCall, expr[0])
|
||||
|
||||
@pg.production("expression : expression Decrement expression")
|
||||
@pg.production("expression : expression Decrement")
|
||||
@pg.production("expression : expression Increment expression")
|
||||
@pg.production("expression : expression Increment")
|
||||
@pg.production("expression : expression PlusInplace expression")
|
||||
@pg.production("expression : expression MinusInplace expression")
|
||||
@pg.production("expression : expression MultiplyInplace expression")
|
||||
@pg.production("expression : expression DivideInplace expression")
|
||||
def sugar_inplace_arithmetic(expr):
|
||||
op = {
|
||||
"Increment": "inc",
|
||||
"Decrement": "dec",
|
||||
"PlusInplace": "add",
|
||||
"MinusInplace": "sub",
|
||||
"MultiplyInplace": "mul",
|
||||
"DivideInplace": "div",
|
||||
}[expr[1].name]
|
||||
args = [] if len(expr) == 2 else [expr[2]] # unary/binary
|
||||
methcall = build_methodcall([op, args], simpleast.MethodCall, expr[0])
|
||||
|
||||
if isinstance(expr[0], simpleast.MethodCall) and expr[0].arguments == []: # attribute
|
||||
return simpleast.Assignment(expr[0].receiver, expr[0].methodname, methcall) # modify inplace
|
||||
|
||||
return build_methodcall([op, args], simpleast.MethodCall, expr[0]) # just increment
|
||||
|
||||
|
||||
@pg.production("expression : expression Less expression")
|
||||
@pg.production("expression : expression LessEqual expression")
|
||||
@pg.production("expression : expression Greater expression")
|
||||
@pg.production("expression : expression GreaterEqual expression")
|
||||
@pg.production("expression : expression Equal expression")
|
||||
@pg.production("expression : expression NotEqual expression")
|
||||
def sugar_comparison(expr):
|
||||
op = {
|
||||
"Less": "less",
|
||||
"LessEqual": "leq",
|
||||
"Greater": "greater",
|
||||
"GreaterEqual": "geq",
|
||||
"Equal": "eq",
|
||||
"NotEqual": "noteq",
|
||||
}[expr[1].name]
|
||||
|
||||
return build_methodcall([op, [expr[2]]], simpleast.MethodCall, expr[0]) # ([name, arg], class, receiver)
|
||||
|
||||
|
||||
@pg.production("expression : expression And expression")
|
||||
@pg.production("expression : expression Or expression")
|
||||
@pg.production("expression : Not expression")
|
||||
def sugar_logical(expr):
|
||||
if len(expr) == 2: # unary
|
||||
return build_methodcall(["not", []], simpleast.MethodCall, expr[1])
|
||||
|
||||
op = {
|
||||
"And": "and",
|
||||
"Or": "or",
|
||||
}[expr[1].name]
|
||||
|
||||
return build_methodcall([op, [expr[2]]], simpleast.MethodCall, expr[0]) # ([name, arg], class, receiver)
|
||||
|
||||
|
||||
@pg.production("expression : OpenBracket expression CloseBracket")
|
||||
|
Reference in New Issue
Block a user