Make IR generation fallible

This commit is contained in:
Emi Simpson 2023-03-04 23:43:26 -05:00
parent 15206f7776
commit 46e59ba918
Signed by: Emi
GPG key ID: A12F2C2FFDC3D847

View file

@ -75,28 +75,38 @@ class Variable(IntEnum):
ASTTerm: TypeAlias = 'ASTNegated | ASTProp'
@dataclass(frozen=True)
class ArgumentsForVariable:
term: Lexeme[Tok]
@dataclass(frozen=True)
class UnidentifiedVariable:
term: Lexeme[Tok]
GenIrError: TypeAlias = ArgumentsForVariable | UnidentifiedVariable
@dataclass(frozen=True)
class ASTNegated:
term: ASTTerm
def make_ir(self, props: Sequence[str], var: Sequence[str]) -> 'IRNeg':
return IRNeg(self.term.make_ir(props, var))
def make_ir(self, props: Sequence[str], var: Sequence[str]) -> 'Result[IRTerm, GenIrError]':
return map_res(IRNeg, self.term.make_ir(props, var))
@dataclass(frozen=True)
class ASTProp:
ident: Lexeme[Tok]
arguments: Sequence[ASTTerm]
def make_ir(self, props: Sequence[str], vars: Sequence[str]) -> 'IRVar | IRProp':
def make_ir(self, props: Sequence[str], vars: Sequence[str]) -> 'Result[IRTerm, GenIrError]':
if self.ident.matched_string in props:
return IRProp(self.ident, [t.make_ir(props, vars) for t in self.arguments])
return map_res(p(IRProp, self.ident), sequence([t.make_ir(props, vars) for t in self.arguments]))
elif self.ident.matched_string in vars:
if len(self.arguments):
raise Exception('Bad arg count!') #TODO
return Err(ArgumentsForVariable(self.ident))
else:
return IRVar(self.ident)
return Ok(IRVar(self.ident))
else:
raise Exception('Unidentified!') #TODO
return Err(UnidentifiedVariable(self.ident))
@dataclass(frozen=True)
class IRProp:
@ -125,10 +135,10 @@ def make_ir(
const_idents: Sequence[Lexeme[Tok]],
func_idents: Sequence[Lexeme[Tok]],
clauses: Sequence[Sequence[ASTTerm]],
) -> Sequence[Sequence[IRTerm]]:
) -> Result[Sequence[Sequence[IRTerm]], GenIrError]:
prop_idents = [l.matched_string for l in (*const_idents, *func_idents, *predicate_idents)]
var_idents = [l.matched_string for l in variable_idents]
return [[term.make_ir(prop_idents, var_idents) for term in clause] for clause in clauses]
return sequence([sequence([term.make_ir(prop_idents, var_idents) for term in clause]) for clause in clauses])
def cons(stack: Sequence[Any]) -> Sequence[Any]:
match stack:
@ -256,8 +266,12 @@ if __name__ == '__main__':
maybe_ast = parser_(lexemes)
match maybe_ast:
case Ok([ast]):
case Ok([Ok(ast)]):
print('\n'.join(' or '.join(str(t) for t in c) for c in ast))
case Ok([Err(ArgumentsForVariable(v))]):
print(f'Semantic error: Arguments listed for variable {repr(v.matched_string)} on line {v.line}:{v.col_start}-{v.col_end}')
case Ok([Err(UnidentifiedVariable(v))]):
print(f'Semantic error: Unidentified identifier {repr(v.matched_string)} on line {v.line}:{v.col_start}-{v.col_end}')
case Ok(huh):
print('Unexpected end result: ', huh)
case Err((Lexeme(token, text, line, col_start, col_end), expected)):