def split_call_semantics(self, stmt: Call, state: State) -> State: if len(stmt.arguments) != 1: error = f"Semantics for multiple arguments of {stmt.name} is not yet implemented!" raise NotImplementedError(error) argument = self.semantics(stmt.arguments[0], state).result result = set() for arg in argument: assert isinstance(arg, Expression) if not isinstance(arg.typ, StringLyraType): error = f"Call to {stmt.name} of argument with unexpected type!" raise ValueError(error) typ = ListLyraType(StringLyraType()) if isinstance(arg, Literal): # "a b c".split() -> ["a", "b", "c"] items = [ Literal(StringLyraType(), val) for val in arg.val.split() ] result.add(ListDisplay(typ, items)) continue elif isinstance(arg, VariableIdentifier): # x.split() result.add(VariableIdentifier(typ, arg.name)) continue elif isinstance(arg, Input): # input().split() result.add(Input(typ)) continue error = f"Call to {stmt.name} of unexpected argument!" raise ValueError(error) state.result = result return state
def strip_call_semantics(self, stmt: Call, state: State, interpreter: Interpreter) -> State: if len(stmt.arguments) != 1: error = f"Semantics for multiple arguments of {stmt.name} is not yet implemented!" raise NotImplementedError(error) argument = self.semantics(stmt.arguments[0], state, interpreter).result result = set() for arg in argument: assert isinstance(arg, Expression) if not isinstance(arg.typ, StringLyraType): error = f"Call to {stmt.name} of argument with unexpected type!" raise ValueError(error) typ = StringLyraType() if isinstance(arg, Input): # input().strip() result.add(Input(typ)) continue elif isinstance(arg, VariableIdentifier): # x.strip() result.add(VariableIdentifier(typ, arg.name)) continue elif isinstance(arg, Subscription): # x[i].strip() result.add(Subscription(typ, arg.target, arg.key)) continue error = f"Call to {stmt.name} of unexpected argument {arg}!" raise ValueError(error) state.result = result return state
def _cast_call_semantics(self, stmt: Call, state: State, typ: LyraType) -> State: """Semantics of a call to 'int' or 'bool'. :param stmt: call to 'int' or 'bool' to be executed :param state: state before executing the call statement :return: state modified by the call statement """ if len(stmt.arguments) != 1: error = f"Semantics for multiple arguments of {stmt.name} is not yet implemented!" raise NotImplementedError(error) argument = self.semantics(stmt.arguments[0], state).result result = set() for expression in argument: if isinstance(expression, Input): result.add(Input(typ)) elif isinstance(expression, Literal): result.add(Literal(typ, expression.val)) elif isinstance(expression, VariableIdentifier): result.add(VariableIdentifier(typ, expression.name)) elif isinstance(expression, Subscription): result.add(Subscription(typ, expression.target, expression.key)) else: error = f"Argument of type {expression.typ} of {stmt.name} is not yet supported!" raise NotImplementedError(error) state.result = result return state
def input_call_semantics(self, stmt: Call, state: State) -> State: """Semantics of a calls to 'input'. :param stmt: call to 'input' to be executed :param state: state before executing the call statement :return: state modified by the call statement """ state.result = {Input(stmt.typ)} return state
def _cast_call_semantics(self, stmt: Call, state, interpreter, typ: LyraType) -> State: """Semantics of a call to 'int', 'bool', or 'float'. :param stmt: call to 'int', 'bool', 'float', or 'str' to be executed :param state: state before executing the call statement :return: state modified by the call statement """ if len(stmt.arguments) != 1: error = f"Semantics for multiple arguments of {stmt.name} is not yet implemented!" raise NotImplementedError(error) argument = self.semantics(stmt.arguments[0], state, interpreter).result result = set() for expression in argument: if isinstance(expression, Input): result.add(Input(typ)) elif isinstance(expression, Literal): result.add(Literal(typ, expression.val)) else: result.add(CastOperation(typ, expression)) state.result = result return state