Make IR generation fallible
This commit is contained in:
parent
15206f7776
commit
46e59ba918
34
grammar.py
34
grammar.py
|
@ -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)):
|
||||
|
|
Loading…
Reference in a new issue