add bf functions, import statement and stdlib (and remove some opcodes). Also fix some bugs in op
This commit is contained in:
parent
287a2a066a
commit
8bd8e3b458
|
@ -69,10 +69,6 @@ def interpret(prog):
|
||||||
return ar
|
return ar
|
||||||
|
|
||||||
|
|
||||||
def format(prog,debug_mode=True):
|
|
||||||
if debug_mode:
|
|
||||||
return ''.join(i for i in prog if i in '[]<>+-.,#')
|
|
||||||
return ''.join(i for i in prog if i in '[]<>+-.,')
|
|
||||||
|
|
||||||
|
|
||||||
def repl():
|
def repl():
|
||||||
|
|
16
grammar.ebnf
16
grammar.ebnf
|
@ -1,12 +1,13 @@
|
||||||
program = statement, {statement}
|
program = statement, {statement}
|
||||||
|
|
||||||
block = "{",{statement}, "}"
|
block = "{",{statement}, "}"
|
||||||
statement = short_statement | while_block | if_block | function_def
|
statement = short_statement | while_block | if_block | function_def | function_bf
|
||||||
short_statement = print | return | input | declaration | assignement | expression | inc-dec, ";"
|
short_statement = print | return | input | declaration | assignement | expression | inc-dec | import, ";"
|
||||||
|
|
||||||
assignement = name, assignement_symbol, expression
|
assignement = name, assignement_symbol, expression
|
||||||
declaration = "var" , name , {",",name}
|
declaration = "var" , name , {",",name}
|
||||||
return = "return", expression
|
return = "return", expression
|
||||||
|
import = "import", string
|
||||||
|
|
||||||
expression = compar_op | function_call
|
expression = compar_op | function_call
|
||||||
|
|
||||||
|
@ -14,9 +15,9 @@ function_call = name, '(',[expression,{','expression,}]
|
||||||
|
|
||||||
|
|
||||||
compar = calcul, [compar_op, calcul]
|
compar = calcul, [compar_op, calcul]
|
||||||
calcul = terme, [('+'|'-'), terme]
|
calcul = terme, {('+'|'-'), terme}
|
||||||
terme = factor [("*"|"/"), factor]
|
terme = factor {("*"|"/"), factor}
|
||||||
factor = val ["**", val]
|
factor = val {"**", val}
|
||||||
val = name | number | "(", expression, ")"
|
val = name | number | "(", expression, ")"
|
||||||
inc-dec = name, ("++" | "--")
|
inc-dec = name, ("++" | "--")
|
||||||
|
|
||||||
|
@ -24,9 +25,12 @@ condition = '(', expression, ')'
|
||||||
while_block = "while", condition, block
|
while_block = "while", condition, block
|
||||||
if_block = "if", condition, block, ["else", block]
|
if_block = "if", condition, block, ["else", block]
|
||||||
function_def = "def", name, '(',[name,{',',name}],')',block
|
function_def = "def", name, '(',[name,{',',name}],')',block
|
||||||
|
function_bf = 'bf',name, '{', brainfuck_code, '}'
|
||||||
|
|
||||||
|
brainfuck_code = {'<'|'>'|'+'|'-'|'.'|','|'['|']'}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bin_op = "+"|"-"|"*"|"/"|"**"
|
bin_op = "+"|"-"|"*"|"/"|"**"
|
||||||
compar_op = ">"|">="|"<"|"<="|"=="
|
compar_op = ">"|">="|"<"|"<="|"=="
|
||||||
assignement_symbol = "="|"+="|"-="|"/="|"*="
|
assignement_symbol = "="|"+="|"-="|"/="|"*="
|
||||||
|
|
34
op.bf
34
op.bf
|
@ -11,6 +11,9 @@ COMPAR :
|
||||||
{add the last part}
|
{add the last part}
|
||||||
|
|
||||||
|
|
||||||
|
Situation à la fin:
|
||||||
|
0 b 0 k
|
||||||
|
|
||||||
EQUALS :
|
EQUALS :
|
||||||
+>[<->[-]]>>[<<<->>>-]<<<
|
+>[<->[-]]>>[<<<->>>-]<<<
|
||||||
|
|
||||||
|
@ -18,16 +21,16 @@ DIFFERENT :
|
||||||
>[<+>[-]]>>[<<<+>>>-]<<<
|
>[<+>[-]]>>[<<<+>>>-]<<<
|
||||||
|
|
||||||
GREATER :
|
GREATER :
|
||||||
>>>[<<<+>>>-]<<<
|
>[-]>>[<<<+>>>-]<<<
|
||||||
|
|
||||||
GREATER OR EQUALS :
|
GREATER OR EQUALS :
|
||||||
+>[<->[-]]<
|
+>[<->[-]]>>[-]<<<
|
||||||
|
|
||||||
SMALLER :
|
SMALLER :
|
||||||
>[<+>[-]]<
|
>[<+>[-]]>>[-]<<<
|
||||||
|
|
||||||
SMALLER OR EQUALS :
|
SMALLER OR EQUALS :
|
||||||
+>>>[<<<->>>-]<<<
|
+>[-]>>[<<<->>>-]<<<
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,12 +49,31 @@ DIV :
|
||||||
[->+>>+<<<]
|
[->+>>+<<<]
|
||||||
<[->+>>+<<<]
|
<[->+>>+<<<]
|
||||||
>>>
|
>>>
|
||||||
[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]+>[<->[-]]<
|
[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]+>[<->[-]]>>[-]<<<
|
||||||
[
|
[
|
||||||
-<[-<->>+<]>[-<+>]
|
-<[-<->>+<]>[-<+>]
|
||||||
<<<+>
|
<<<+>
|
||||||
[->>+>+<<<]>>>[-<<<+>>>]<<
|
[->>+>+<<<]>>>[-<<<+>>>]<<
|
||||||
[->>+>+<<<]>>>[-<<<+>>>]<
|
[->>+>+<<<]>>>[-<<<+>>>]<
|
||||||
<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]>>>[<<<+>>>-]<<<
|
<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]+>[<->[-]]>>[-]<<<
|
||||||
]
|
]
|
||||||
<[-]<[-]<
|
<[-]<[-]<
|
||||||
|
|
||||||
|
|
||||||
|
MOD :
|
||||||
|
=====
|
||||||
|
[->+>>+<<<]
|
||||||
|
<[->+>>+<<<]
|
||||||
|
>>>
|
||||||
|
[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]+>[<->[-]]>>[-]<<<
|
||||||
|
[
|
||||||
|
-<[-<->>+<]>[-<+>]
|
||||||
|
<<
|
||||||
|
[->>+>+<<<]>>>[-<<<+>>>]<<
|
||||||
|
[->>+>+<<<]>>>[-<<<+>>>]<
|
||||||
|
<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]+>[<->[-]]>>[-]<<<
|
||||||
|
]
|
||||||
|
<[-]<[-<+>]<
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
STDLIB
|
||||||
|
The comment after the bf function is the number of arguments
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
bf putc {{ //1
|
||||||
|
.
|
||||||
|
}}
|
||||||
|
|
||||||
|
bf scanc {{ //0
|
||||||
|
>,
|
||||||
|
}}
|
||||||
|
|
||||||
|
bf debug {{ //0
|
||||||
|
#>
|
||||||
|
}}
|
||||||
|
|
||||||
|
def print_int(n){
|
||||||
|
var i, val;
|
||||||
|
i = 1;
|
||||||
|
while (i <= n){
|
||||||
|
i *= 10;
|
||||||
|
}
|
||||||
|
i /= 10;
|
||||||
|
while (i >= 1){
|
||||||
|
val = n / i;
|
||||||
|
n %= i;
|
||||||
|
putc(val + 48);
|
||||||
|
i /= 10;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
from collections import ChainMap
|
||||||
|
|
||||||
|
import to_bf_compiler as compiler
|
||||||
|
|
||||||
|
BUILT_IN_FUNCTIONS = ChainMap({})
|
||||||
|
|
||||||
|
BUILT_IN_FUNCTIONS['putc'] = [('PUTC',)]
|
||||||
|
BUILT_IN_FUNCTIONS['scanc'] =[('SCANC',)]
|
||||||
|
BUILT_IN_FUNCTIONS['debug'] = [('DEBUG',)]
|
||||||
|
|
||||||
|
func_to_compile = []
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func_to_compile.append(
|
||||||
|
('print_int',"""
|
||||||
|
|
||||||
|
def print_int(n){
|
||||||
|
var i, val;
|
||||||
|
i = 1;
|
||||||
|
while (i <= n){
|
||||||
|
i *= 10;
|
||||||
|
}
|
||||||
|
i /= 10;
|
||||||
|
while (i >= 1){
|
||||||
|
val = n / i;
|
||||||
|
n %= i;
|
||||||
|
putc(val + 48);
|
||||||
|
i /= 10;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
"""))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def compile_func(name,func):
|
||||||
|
ast = compiler.compile(func,2)
|
||||||
|
ir = compiler.Ast_to_IR(ast,BUILT_IN_FUNCTIONS) #on peut utiliser toutes les fonctions définis avant
|
||||||
|
ir.convert()
|
||||||
|
return ir.functions[name]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for name, func in func_to_compile:
|
||||||
|
BUILT_IN_FUNCTIONS[name] = compile_func(name,func)
|
||||||
|
|
||||||
|
|
|
@ -9,18 +9,19 @@ os.system('color')
|
||||||
REGEXS = [(re.compile(i),j) for i,j in (
|
REGEXS = [(re.compile(i),j) for i,j in (
|
||||||
(r'\s+','WHITESPACE'),
|
(r'\s+','WHITESPACE'),
|
||||||
(r'//[^\n]*|/\*(?s:.)*\*/','COMMENTS'),
|
(r'//[^\n]*|/\*(?s:.)*\*/','COMMENTS'),
|
||||||
(r'if|for|while|else|var|def|return','KEYWORD'),
|
(r'if|while|else|var|def|return|bf|import','KEYWORD'),
|
||||||
|
|
||||||
|
(r'\{\{[^}]*\}\}','BRAINFUCK_CODE'),
|
||||||
(r'>=|<=|==|>|<|!=','COMPAR_OP'),
|
(r'>=|<=|==|>|<|!=','COMPAR_OP'),
|
||||||
(r'\+=|-=|\*=|/=|=','ASSIGNEMENT_OP'),
|
(r'\+=|%=|-=|\*=|/=|=','ASSIGNEMENT_OP'),
|
||||||
(r'\+\+|--','INC_DEC_OP'),
|
(r'\+\+|--','INC_DEC_OP'),
|
||||||
(r'\+|\*\*|\*|-|/','BIN_OP'),
|
(r'\+|\*\*|\*|-|/|%','BIN_OP'),
|
||||||
(r'\(|\)|\{|\}|;|,','CONTROL_CHAR'),
|
(r'\(|\)|\{|\}|;|,','CONTROL_CHAR'),
|
||||||
|
|
||||||
(r'[a-zA-Z]\w*','IDENTIFIERS'),
|
(r'[a-zA-Z]\w*','IDENTIFIERS'),
|
||||||
(r'\d[\d_]*','NUMBERS'),
|
(r'\d[\d_]*','NUMBERS'),
|
||||||
(r"'.'",'CHAR')
|
(r"'.'",'CHAR'),
|
||||||
|
(r'"(\\.|[^"\n])*"','STRING'),
|
||||||
)]
|
)]
|
||||||
|
|
||||||
USELESS_TAGS = ('WHITESPACE','COMMENTS')
|
USELESS_TAGS = ('WHITESPACE','COMMENTS')
|
||||||
|
@ -47,6 +48,34 @@ def lex(program,keep_whitespace=False):
|
||||||
def clean_tokens(tokens):
|
def clean_tokens(tokens):
|
||||||
return [token for token in tokens if token.tag not in USELESS_TAGS]
|
return [token for token in tokens if token.tag not in USELESS_TAGS]
|
||||||
|
|
||||||
|
def format_bf(prog,debug_mode=True):
|
||||||
|
if debug_mode:
|
||||||
|
t = []
|
||||||
|
index = 0
|
||||||
|
while index < len(prog):
|
||||||
|
if prog[index] in '[]<>+-.,':
|
||||||
|
t.append(prog[index])
|
||||||
|
index += 1
|
||||||
|
elif prog[index] == '#':
|
||||||
|
t.append('#')
|
||||||
|
index += 1
|
||||||
|
try:
|
||||||
|
if prog[index] == '(':
|
||||||
|
index += 1
|
||||||
|
t.append('(')
|
||||||
|
while prog[index] != ')':
|
||||||
|
t.append(prog[index])
|
||||||
|
index+=1
|
||||||
|
t.append(')')
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
index+=1
|
||||||
|
return ''.join(t)
|
||||||
|
|
||||||
|
return ''.join(i for i in prog if i in '[]<>+-.,')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#****************************
|
#****************************
|
||||||
|
|
||||||
|
@ -57,12 +86,14 @@ BlockNode = namedtuple('BlockNode',('list_of_statement'))
|
||||||
IfNode = namedtuple('IfNode',('condition','block','else_block'))
|
IfNode = namedtuple('IfNode',('condition','block','else_block'))
|
||||||
WhileNode = namedtuple('WhileNode',('condition','block'))
|
WhileNode = namedtuple('WhileNode',('condition','block'))
|
||||||
FunctionDefNode = namedtuple('FunctionDefNode',('name','args','block'))
|
FunctionDefNode = namedtuple('FunctionDefNode',('name','args','block'))
|
||||||
|
BfDefNode = namedtuple('BfDefNode',('name','code'))
|
||||||
|
|
||||||
AssignementNode = namedtuple('AssignementNode',('target','operator','expression'))
|
AssignementNode = namedtuple('AssignementNode',('target','operator','expression'))
|
||||||
IncDecNode = namedtuple('IncDecNode',('name','operator'))
|
IncDecNode = namedtuple('IncDecNode',('name','operator'))
|
||||||
DeclarationNode = namedtuple('DeclarationNode',('names'))
|
DeclarationNode = namedtuple('DeclarationNode',('names'))
|
||||||
FunctionCallNode = namedtuple('FunctionCallNode',('name','args'))
|
FunctionCallNode = namedtuple('FunctionCallNode',('name','args'))
|
||||||
ReturnNode = namedtuple('ReturnNode',('expr'))
|
ReturnNode = namedtuple('ReturnNode',('expr'))
|
||||||
|
ImportNode = namedtuple('ImportNode',('path',))
|
||||||
BinOpNode = namedtuple('BinOpNode',('left','op','right'))
|
BinOpNode = namedtuple('BinOpNode',('left','op','right'))
|
||||||
|
|
||||||
IdentifierNode = namedtuple('IdentifierNode',('name'))
|
IdentifierNode = namedtuple('IdentifierNode',('name'))
|
||||||
|
@ -105,6 +136,9 @@ class Parser:
|
||||||
nodes = []
|
nodes = []
|
||||||
while 1:
|
while 1:
|
||||||
statement = self.statement()
|
statement = self.statement()
|
||||||
|
if isinstance(statement,ImportNode):
|
||||||
|
ast = get_ast(statement.path)
|
||||||
|
nodes.extend(ast)
|
||||||
if statement:
|
if statement:
|
||||||
nodes.append(statement)
|
nodes.append(statement)
|
||||||
else:
|
else:
|
||||||
|
@ -131,18 +165,15 @@ class Parser:
|
||||||
return BlockNode(nodes)
|
return BlockNode(nodes)
|
||||||
|
|
||||||
def statement(self):
|
def statement(self):
|
||||||
#print(f"enter statement ({self.pos})")
|
for func in (self.short_statement,self.while_block, self.if_block,self.function_block, self.bf_block):
|
||||||
for func in (self.short_statement,self.while_block, self.if_block,self.function_block):
|
|
||||||
node = func()
|
node = func()
|
||||||
if node:
|
if node:
|
||||||
#cprint("statement",'green')
|
|
||||||
return node
|
return node
|
||||||
#cprint("no statement",'red')
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def short_statement(self):
|
def short_statement(self):
|
||||||
#print(f"enter short_statement ({self.pos})")
|
#print(f"enter short_statement ({self.pos})")
|
||||||
for func in (self.declaration, self.assignement,self.inc_dec,self.expression,self.return_):
|
for func in (self.declaration, self.assignement,self.inc_dec,self.expression,self.return_,self.import_):
|
||||||
node = func()
|
node = func()
|
||||||
if node:
|
if node:
|
||||||
if self.accept_text(";"):
|
if self.accept_text(";"):
|
||||||
|
@ -153,6 +184,14 @@ class Parser:
|
||||||
#cprint("no short_statement",'red')
|
#cprint("no short_statement",'red')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def import_(self):
|
||||||
|
if not self.accept_text('import'):
|
||||||
|
return None
|
||||||
|
path = self.accept_tag('STRING')
|
||||||
|
if not path:
|
||||||
|
raise SyntaxError('Bad import')
|
||||||
|
return ImportNode(path.text[1:-1])
|
||||||
|
|
||||||
def return_(self):
|
def return_(self):
|
||||||
if not self.accept_text('return'):
|
if not self.accept_text('return'):
|
||||||
return None
|
return None
|
||||||
|
@ -260,19 +299,22 @@ class Parser:
|
||||||
if not terme1:
|
if not terme1:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
op = None
|
while 1:
|
||||||
sym = self.accept_text('+')
|
op = None
|
||||||
if sym:
|
sym = self.accept_text('+')
|
||||||
op = sym
|
if sym:
|
||||||
sym = self.accept_text('-')
|
op = sym
|
||||||
if sym:
|
sym = self.accept_text('-')
|
||||||
op = sym
|
if sym:
|
||||||
|
op = sym
|
||||||
|
if not op:
|
||||||
|
return terme1
|
||||||
|
|
||||||
if op:
|
if op:
|
||||||
terme2 = self.terme()
|
terme2 = self.terme()
|
||||||
if not terme2:
|
if not terme2:
|
||||||
raise SyntaxError("missing second term in calcul")
|
raise SyntaxError("missing second term in calcul")
|
||||||
return BinOpNode(terme1,op.text,terme2)
|
terme1 = BinOpNode(terme1,op.text,terme2)
|
||||||
return terme1
|
return terme1
|
||||||
|
|
||||||
|
|
||||||
|
@ -282,19 +324,25 @@ class Parser:
|
||||||
if not factor1:
|
if not factor1:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
op = None
|
while 1:
|
||||||
sym = self.accept_text('*')
|
op = None
|
||||||
if sym:
|
sym = self.accept_text('*')
|
||||||
op = sym
|
if sym:
|
||||||
sym = self.accept_text('/')
|
op = sym
|
||||||
if sym:
|
sym = self.accept_text('/')
|
||||||
op = sym
|
if sym:
|
||||||
|
op = sym
|
||||||
|
sym = self.accept_text('%')
|
||||||
|
if sym:
|
||||||
|
op = sym
|
||||||
|
|
||||||
if op:
|
if op:
|
||||||
factor2 = self.factor()
|
factor2 = self.factor()
|
||||||
if not factor2:
|
if not factor2:
|
||||||
raise SyntaxError("missing second factor in terme")
|
raise SyntaxError("missing second factor in terme")
|
||||||
return BinOpNode(factor1,op.text,factor2)
|
factor1 = BinOpNode(factor1,op.text,factor2)
|
||||||
|
else:
|
||||||
|
break
|
||||||
return factor1
|
return factor1
|
||||||
|
|
||||||
def factor(self):
|
def factor(self):
|
||||||
|
@ -302,12 +350,11 @@ class Parser:
|
||||||
val = self.value()
|
val = self.value()
|
||||||
if not val:
|
if not val:
|
||||||
return None
|
return None
|
||||||
op = self.accept_text('**')
|
while self.accept_text('**'):
|
||||||
if op:
|
val2 = self.value()
|
||||||
val2 = self.value()
|
if not val2:
|
||||||
if not val2:
|
raise SyntaxError("missing second val un factor")
|
||||||
raise SyntaxError("missing second val un factor")
|
val = BinOpNode(val,'**',val2)
|
||||||
return BinOpNode(val,op.text,val2)
|
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def value(self):
|
def value(self):
|
||||||
|
@ -408,6 +455,19 @@ class Parser:
|
||||||
|
|
||||||
return FunctionDefNode(name.text,args,block)
|
return FunctionDefNode(name.text,args,block)
|
||||||
|
|
||||||
|
def bf_block(self):
|
||||||
|
if not self.accept_text('bf'):
|
||||||
|
return None
|
||||||
|
name = self.accept_tag('IDENTIFIERS')
|
||||||
|
if not name:
|
||||||
|
raise SyntaxError("A bf function need a name")
|
||||||
|
|
||||||
|
code = self.accept_tag('BRAINFUCK_CODE')
|
||||||
|
if not code:
|
||||||
|
raise SyntaxError("Bad bf block")
|
||||||
|
code = format_bf(code.text[2:-2])
|
||||||
|
return BfDefNode(name.text,code)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -417,22 +477,23 @@ def parse(prog):
|
||||||
return parser.program()
|
return parser.program()
|
||||||
|
|
||||||
|
|
||||||
|
def get_ast(path):
|
||||||
|
with open(path) as file:
|
||||||
|
code = file.read()
|
||||||
|
tokens = lex(code)
|
||||||
|
ast = Parser(tokens).parse()
|
||||||
|
return ast.list_of_statement
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#***************
|
#***************
|
||||||
|
|
||||||
BUILT_IN_FUNCTIONS = ChainMap({
|
|
||||||
'putc':[('PUTC',)],
|
|
||||||
'scanc':[('SCANC',)],
|
|
||||||
'mod':[
|
|
||||||
|
|
||||||
('')
|
|
||||||
|
|
||||||
],
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
class Ast_to_IR:
|
class Ast_to_IR:
|
||||||
|
|
||||||
def __init__(self,ast,functions=BUILT_IN_FUNCTIONS):
|
def __init__(self,ast,functions=None):
|
||||||
|
if functions is None:
|
||||||
|
functions = ChainMap({})
|
||||||
self.ast = ast
|
self.ast = ast
|
||||||
self.functions = functions
|
self.functions = functions
|
||||||
|
|
||||||
|
@ -456,6 +517,9 @@ class Ast_to_IR:
|
||||||
for statement in statements:
|
for statement in statements:
|
||||||
if isinstance(statement,FunctionDefNode):
|
if isinstance(statement,FunctionDefNode):
|
||||||
self.functions[statement.name] = Ast_to_IR(statement,self.functions).convert()
|
self.functions[statement.name] = Ast_to_IR(statement,self.functions).convert()
|
||||||
|
elif isinstance(statement,BfDefNode):
|
||||||
|
code = statement.code
|
||||||
|
self.functions[statement.name] = [('BF',code,statement.name)]
|
||||||
|
|
||||||
|
|
||||||
vars_ = []
|
vars_ = []
|
||||||
|
@ -573,6 +637,8 @@ methods = {
|
||||||
WhileNode: Ast_to_IR.while_to_ir,
|
WhileNode: Ast_to_IR.while_to_ir,
|
||||||
IfNode: Ast_to_IR.if_to_ir,
|
IfNode: Ast_to_IR.if_to_ir,
|
||||||
IncDecNode: Ast_to_IR.inc_dec_to_ir,
|
IncDecNode: Ast_to_IR.inc_dec_to_ir,
|
||||||
|
BfDefNode: lambda self,node:None,
|
||||||
|
ImportNode: lambda self,node:None,
|
||||||
}
|
}
|
||||||
default = Ast_to_IR.expression_statement_to_ir
|
default = Ast_to_IR.expression_statement_to_ir
|
||||||
|
|
||||||
|
@ -587,6 +653,10 @@ def init_function(nb,name):
|
||||||
def end_function(nb,name):
|
def end_function(nb,name):
|
||||||
return '<[-]' * nb + '>' * nb + (f"[-{'<'*nb}+{'>'*nb}]" if nb else "") + '<' * nb+ f' END_FUNCTION {name}'
|
return '<[-]' * nb + '>' * nb + (f"[-{'<'*nb}+{'>'*nb}]" if nb else "") + '<' * nb+ f' END_FUNCTION {name}'
|
||||||
|
|
||||||
|
def bf(code,name):
|
||||||
|
return f"BF {name}\n{code}\nEND_BF"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def assign(val,name):
|
def assign(val,name):
|
||||||
return f"{'<'*val}[-]{'>'*val}[-{'<'*val}+{'>'*val}]< ASSIGN {name}"
|
return f"{'<'*val}[-]{'>'*val}[-{'<'*val}+{'>'*val}]< ASSIGN {name}"
|
||||||
|
@ -614,22 +684,25 @@ def bin_op(op):
|
||||||
elif op == '*':
|
elif op == '*':
|
||||||
bf = "<[->>+<<]>[->[-<<+>>>+<]>[-<+>]<<]>[-]<<"
|
bf = "<[->>+<<]>[->[-<<+>>>+<]>[-<+>]<<]>[-]<<"
|
||||||
elif op == '/':
|
elif op == '/':
|
||||||
bf = "[->+>>+<<<]<[->+>>+<<<]>>>[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]+>[<->[-]]<"
|
bf = ("[->+>>+<<<]<[->+>>+<<<]>>>[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]+>[<->[-]]>>[-]<<<"
|
||||||
"[-<[-<->>+<]>[-<+>]<<<+>[->>+>+<<<]>>>[-<<<+>>>]<<[->>+>+<<<]>>>[-<<<+>>>]<<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>"
|
"[-<[-<->>+<]>[-<+>]<<<+>[->>+>+<<<]>>>[-<<<+>>>]<<[->>+>+<<<]>>>[-<<<+>>>]<<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>"
|
||||||
">[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]>>>[<<<+>>>-]<<<#]<[-]<[-]<"
|
">[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]+>[<->[-]]>>[-]<<<]<[-]<[-]<")
|
||||||
|
elif op == '%':
|
||||||
|
bf = "[->+>>+<<<]<[->+>>+<<<]>>>[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]+>[<->[-]]>>[-]<<<" \
|
||||||
|
"[-<[-<->>+<]>[-<+>]<<[->>+>+<<<]>>>[-<<<+>>>]<<[->>+>+<<<]>>>[-<<<+>>>]<<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>" \
|
||||||
|
"[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]+>[<->[-]]>>[-]<<<]<[-]<[-<+>]<"
|
||||||
elif op == '==':
|
elif op == '==':
|
||||||
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + "+>[<->[-]]>>[<<<->>>-]<<<"
|
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + "+>[<->[-]]>>[<<<->>>-]<<<"
|
||||||
elif op == '!=':
|
elif op == '!=':
|
||||||
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + ">[<+>[-]]>>[<<<+>>>-]<<<"
|
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + ">[<+>[-]]>>[<<<+>>>-]<<<"
|
||||||
elif op == '>':
|
elif op == '>':
|
||||||
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + ">>>[<<<+>>>-]<<<"
|
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + ">[-]>>[<<<+>>>-]<<<"
|
||||||
elif op == '>=':
|
elif op == '>=':
|
||||||
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + "+>[<->[-]]<"
|
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + "+>[<->[-]]>>[-]<<<"
|
||||||
elif op == '<':
|
elif op == '<':
|
||||||
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + ">[<+>[-]]<"
|
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + ">[<+>[-]]>>[-]<<<"
|
||||||
elif op == '<=':
|
elif op == '<=':
|
||||||
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + "+>>>[<<<->>>-]<<<"
|
bf = "<[>[->+>+<<]>>[-<<+>>]+<[>-<[-]]>[->+>+<<]>>[-<<+>>]<[<<<<[-]+>+>>>-]<<<-<-]" + "+>[-]>>[<<<->>>-]<<<"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception(f"bin_op {op} not implemented yet")
|
raise Exception(f"bin_op {op} not implemented yet")
|
||||||
|
@ -654,12 +727,6 @@ def else_end():
|
||||||
def if_end():
|
def if_end():
|
||||||
return "<]>[-]<< IF_END"
|
return "<]>[-]<< IF_END"
|
||||||
|
|
||||||
def putc():
|
|
||||||
return ". PRINT"
|
|
||||||
|
|
||||||
def scanc():
|
|
||||||
return ", INPUT"
|
|
||||||
|
|
||||||
|
|
||||||
def compile_ir(ir):
|
def compile_ir(ir):
|
||||||
return '\n'.join(globals()[i[0].lower()](*i[1:]) for i in ir)
|
return '\n'.join(globals()[i[0].lower()](*i[1:]) for i in ir)
|
||||||
|
|
Loading…
Reference in New Issue