diff --git a/README.md b/README.md index 722127a..dc67a15 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Todo - [ ] Error handling(so it wont just print sly: unexpected token or whatever it says) -- [ ] Handle comparisons properly(==,!=,<=,>=,<,>) -- [ ] Proper readme about files \ No newline at end of file +- [ ] Proper readme about files +- [ ] Make cpq.py act as a cmd util - get input and output and such \ No newline at end of file diff --git a/cpq.py b/cpq.py index 0e7d962..5b2970d 100644 --- a/cpq.py +++ b/cpq.py @@ -18,11 +18,22 @@ a: int; { while(a < 10) { a = a + 1; - if(a == 5) + if(a >= 6 || a == 5) break; else a = a + 0; } + output(a); + switch(a * 5) { + case 1: + a = 5; + break; + case 5: + output(a); + default: + break; + } + output(a); } ''' diff --git a/lexer.py b/lexer.py index e8d9a47..bf3d7b7 100644 --- a/lexer.py +++ b/lexer.py @@ -15,12 +15,12 @@ class Lexer(sly.Lexer): literals = { '(', ')', '{', '}', ',', ':', ';', '=' } # define each token - RELOP = r'(==|!=|<|>|>=|<=)' + RELOP = r'(==|!=|<=|>=|>|<)' ADDOP = r'(\+|-)' MULOP = r'(\*|/)' - OR = '\|\|' - AND = '&&' - NOT = '!' + OR = r'\|\|' + AND = r'&&' + NOT = r'!' CAST = r'static_cast<(int|float)>' ID = r'[a-zA-Z][a-zA-Z0-9]*' diff --git a/parser.py b/parser.py index f2a570f..f36ec2d 100644 --- a/parser.py +++ b/parser.py @@ -170,8 +170,13 @@ class Parser(sly.Parser): self.lines[c.line + 1] = f'JMPZ {c.end} {cmp}' for b in c.breaks: 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 self.lines[b] = break_line + return Statement([]) @_('caselist CASE NUM case_check ":" stmtlist') @@ -181,7 +186,8 @@ class Parser(sly.Parser): self.had_errors = True print_err(f'Invalid case constant at line {p.lineno}: Expected an integer but found a float') # 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] 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() self.lines.append(f'ITOR {new_term} {rhs}') rhs = new_term - # TODO fix this and make it take care of all < > <= >= == != please yes thank you - command = ('R' if float_op else 'I') + ('ADD' if p[1] == '+' else 'SUB') + # RELOP to command map + 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() 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) @_('expression ADDOP term')