properly handle relop and fix switch cases
This commit is contained in:
parent
b17f895f0a
commit
ae2337376c
4 changed files with 32 additions and 10 deletions
|
@ -1,5 +1,5 @@
|
||||||
# Todo
|
# Todo
|
||||||
|
|
||||||
- [ ] Error handling(so it wont just print sly: unexpected token or whatever it says)
|
- [ ] Error handling(so it wont just print sly: unexpected token or whatever it says)
|
||||||
- [ ] Handle comparisons properly(==,!=,<=,>=,<,>)
|
- [ ] Proper readme about files
|
||||||
- [ ] Proper readme about files
|
- [ ] Make cpq.py act as a cmd util - get input and output and such
|
13
cpq.py
13
cpq.py
|
@ -18,11 +18,22 @@ a: int;
|
||||||
{
|
{
|
||||||
while(a < 10) {
|
while(a < 10) {
|
||||||
a = a + 1;
|
a = a + 1;
|
||||||
if(a == 5)
|
if(a >= 6 || a == 5)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
a = a + 0;
|
a = a + 0;
|
||||||
}
|
}
|
||||||
|
output(a);
|
||||||
|
switch(a * 5) {
|
||||||
|
case 1:
|
||||||
|
a = 5;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
output(a);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
output(a);
|
||||||
|
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
|
|
8
lexer.py
8
lexer.py
|
@ -15,12 +15,12 @@ class Lexer(sly.Lexer):
|
||||||
literals = { '(', ')', '{', '}', ',', ':', ';', '=' }
|
literals = { '(', ')', '{', '}', ',', ':', ';', '=' }
|
||||||
|
|
||||||
# define each token
|
# define each token
|
||||||
RELOP = r'(==|!=|<|>|>=|<=)'
|
RELOP = r'(==|!=|<=|>=|>|<)'
|
||||||
ADDOP = r'(\+|-)'
|
ADDOP = r'(\+|-)'
|
||||||
MULOP = r'(\*|/)'
|
MULOP = r'(\*|/)'
|
||||||
OR = '\|\|'
|
OR = r'\|\|'
|
||||||
AND = '&&'
|
AND = r'&&'
|
||||||
NOT = '!'
|
NOT = r'!'
|
||||||
CAST = r'static_cast<(int|float)>'
|
CAST = r'static_cast<(int|float)>'
|
||||||
|
|
||||||
ID = r'[a-zA-Z][a-zA-Z0-9]*'
|
ID = r'[a-zA-Z][a-zA-Z0-9]*'
|
||||||
|
|
17
parser.py
17
parser.py
|
@ -170,8 +170,13 @@ class Parser(sly.Parser):
|
||||||
self.lines[c.line + 1] = f'JMPZ {c.end} {cmp}'
|
self.lines[c.line + 1] = f'JMPZ {c.end} {cmp}'
|
||||||
for b in c.breaks:
|
for b in c.breaks:
|
||||||
self.lines[b] = break_line
|
self.lines[b] = break_line
|
||||||
|
if len(cases) > 0:
|
||||||
|
last_case = cases[-1]
|
||||||
|
# modify the last jump(that skips over the next check) to not skip the default case
|
||||||
|
self.lines[last_case.end - 1] = f'JUMP {last_case.end}' # it is stupid, but an optimizer will hae no problem fixing it
|
||||||
for b in p[8].breaks: # breaks in default
|
for b in p[8].breaks: # breaks in default
|
||||||
self.lines[b] = break_line
|
self.lines[b] = break_line
|
||||||
|
return Statement([])
|
||||||
|
|
||||||
|
|
||||||
@_('caselist CASE NUM case_check ":" stmtlist')
|
@_('caselist CASE NUM case_check ":" stmtlist')
|
||||||
|
@ -181,7 +186,8 @@ class Parser(sly.Parser):
|
||||||
self.had_errors = True
|
self.had_errors = True
|
||||||
print_err(f'Invalid case constant at line {p.lineno}: Expected an integer but found a float')
|
print_err(f'Invalid case constant at line {p.lineno}: Expected an integer but found a float')
|
||||||
# continue as if nothing happend
|
# continue as if nothing happend
|
||||||
self.lines.append(f'JUMP {len(self.lines) + 2}') # Jump over the next comparison in the case of fallthrough
|
self.lines.append(f'JUMP {len(self.lines) + 3}') # Jump over the next comparison in the case of fallthrough
|
||||||
|
|
||||||
line = p[3]
|
line = p[3]
|
||||||
return p[0] + [ Case(p[2], line, len(self.lines), p[5].breaks) ]
|
return p[0] + [ Case(p[2], line, len(self.lines), p[5].breaks) ]
|
||||||
|
|
||||||
|
@ -260,10 +266,15 @@ class Parser(sly.Parser):
|
||||||
new_term = self.next_temp()
|
new_term = self.next_temp()
|
||||||
self.lines.append(f'ITOR {new_term} {rhs}')
|
self.lines.append(f'ITOR {new_term} {rhs}')
|
||||||
rhs = new_term
|
rhs = new_term
|
||||||
# TODO fix this and make it take care of all < > <= >= == != please yes thank you
|
# RELOP to command map
|
||||||
command = ('R' if float_op else 'I') + ('ADD' if p[1] == '+' else 'SUB')
|
com_map = { '<': 'LSS', '>': 'GRT', '==': 'EQL', '!=': 'NQL', '<=': 'GRT', '>=': 'LSS' }
|
||||||
|
# if we need to negate(since quad doesnt have a built in support for it)
|
||||||
|
should_negate = [ '<=', '>=' ]
|
||||||
|
command = ('R' if float_op else 'I') + com_map[p[1]]
|
||||||
result = self.next_temp()
|
result = self.next_temp()
|
||||||
self.lines.append(f'{command} {result} {lhs} {rhs}')
|
self.lines.append(f'{command} {result} {lhs} {rhs}')
|
||||||
|
if p[1] in should_negate:
|
||||||
|
self.lines.append(f'IEQL {result} {result} 0')
|
||||||
return Expression(result, False)
|
return Expression(result, False)
|
||||||
|
|
||||||
@_('expression ADDOP term')
|
@_('expression ADDOP term')
|
||||||
|
|
Loading…
Reference in a new issue