def add_attr(self, dec: Declarable, value: Optional[d_Thing] = None, use_ref: bool = False) -> d_Thing: ref = None if dec.name is None: raise d_CriticalError("A declarable had no name") _check_for_duplicates(self, dec.name) if value: res = check_value(value, dec) if res: raise d_TypeMismatchError( f"Cannot assign {res.actual} to {res.expected}{res.extra}") if dec.type_ == d_Grammar.PRIMITIVE_THING: value.can_be_anything = True if use_ref: # Use a ref to hide the original name without changing it # Currently only used for function parameters afaik ref = d_Ref(dec.name, value) else: value.name = dec.name else: value = _type_to_obj(dec) fin_val = ref or value fin_var = d_Variable(fin_val.name) if isinstance(self, d_Inst): fin_var = self.compose_prefix(fin_val.name) self.attrs[fin_var] = fin_val return value
def get_parents(self) -> Optional[d_List]: p = d_Variable(PARENTS) if p not in self.attrs: return None parents = self.attrs[p] if not isinstance(parents, d_List): raise d_TypeMismatchError("Parents must be a list") parents.contained_type = d_Grammar.VALUE_CLASS parents.can_be_anything = False _check_list_type(parents) # Parents must be a list of Classes return parents
def set_value(self, new_value: d_Thing) -> None: self.is_null = new_value.is_null if isinstance(new_value, d_List): # listOf Str = ['1', '2']; self.list_ = new_value.list_ _check_list_type(self) elif self.can_be_anything: super().set_value(new_value) elif isinstance(new_value, d_Thing): # type: ignore raise d_TypeMismatchError( f"Cannot assign {new_value.public_type} to List") else: raise d_CriticalError("Unrecognized type for list assignment")
def _check_list_type(list_: d_List) -> None: if list_.can_be_anything: list_.contained_type = d_Grammar.VALUE_THING return elif list_.contained_type == d_Grammar.VALUE_THING: return err = False for ele in _traverse(list_.list_): res = check_value(ele, Declarable(list_.contained_type)) if res: raise d_TypeMismatchError( f"List of type '{res.expected}' contained '{res.actual}'{res.extra}" )
def set_value(self, val: d_Thing) -> None: self.is_null = val.is_null if isinstance(self, d_Inst) and isinstance(val, d_Inst): self.attrs = val.attrs elif type(self) == type(val): self.attrs = val.attrs # type: ignore self.parent_scope = val.parent_scope # type: ignore self.view = val.view # type: ignore self.path = val.path # type: ignore elif self.can_be_anything: super().set_value(val) else: # isinstance(val, d_Thing): raise d_TypeMismatchError( f"Cannot assign {val.public_type} to {self.public_type}" # type: ignore )
def add_attr(self, dec: Declarable, value: Optional[d_Thing]) -> d_Thing: result = super().add_attr(dec, value=value) # We set the custom 'priority_num' of the new attribute # to the current lang 'Priority' # Every variable must keep track of the priority at the time it was declared. priority = 0 p = d_Variable(PRIORITY) if p in self.attrs: item = self.attrs[p] if not isinstance(item, d_Str): raise d_TypeMismatchError("Priority must be of type Str") priority = int(item.str_) if not hasattr(result, "priority_num"): result.priority = priority # type: ignore return result
def __init__(self, value: d_Thing, func: d_Func, orig_loc: CodeLocation) -> None: if value.grammar == d_Grammar.NULL: super().__init__(Token(d_Grammar.NULL, orig_loc)) return_declarable = Declarable(type_=func.return_, listof=func.return_list) res = check_value(value, return_declarable) if res: raise d_TypeMismatchError( f"Expected '{res.expected}' for return, got '{res.actual}'{res.extra}" ) if isinstance(value, d_List): super().__init__(Token(d_Grammar.VALUE_LIST, orig_loc, thing=value)) elif isinstance(func.return_, d_Class): super().__init__(Token(d_Grammar.VALUE_INST, orig_loc, thing=value)) elif isinstance(value, d_Thing): # type: ignore super().__init__(Token(func.return_, func.call_loc, thing=value))
def _get_func_args(inter: InterpretContext, func: d_Func) -> None: func.call_loc = copy.deepcopy(inter.curr_tok.loc) arg_locs = _arg_list(inter, d_Grammar.PAREN_RIGHT) miss = abs(len(func.parameters) - len(arg_locs)) name = func.pub_name() for param, arg_loc in zip_longest(func.parameters, arg_locs): param: Declarable arg_loc: ArgumentLocation if not arg_loc: raise d_SyntaxError(f"{name} missing {miss} required arguments") elif not param: # TODO: implement proper k-args functionality raise d_SyntaxError(f"{name} given {miss} too many arguments") else: res = check_value(arg_loc.thing, param) if res: o = f"{name} expected '{res.expected}', got '{res.actual}'{res.extra}" raise d_TypeMismatchError(o, arg_loc.loc) func.add_attr(param, arg_loc.thing, use_ref=True)
def _simple_set_value(self: simple_types, val: d_Thing) -> None: # Always set null, but still need to check that assignment was allowed self.is_null = val.is_null # Check if items match, then just assign if val.grammar == d_Grammar.VALUE_NULL: pass elif isinstance(self, d_Str) and isinstance(val, d_Str): self.str_ = val.str_ elif isinstance(self, d_Bool) and isinstance(val, d_Bool): self.bool_ = val.bool_ elif isinstance(self, d_Num) and isinstance(val, d_Num): self.num = val.num elif isinstance(self, d_JSON) and isinstance(val, d_JSON): self.json_ = val.json_ elif self.can_be_anything: # maybe self was originally a Thing and is being reassigned # Thing test = true; # test = ['dog', 'bird']; super(self.__class__, self).set_value(val) # type: ignore else: # elif isinstance(val, d_Thing): # type: ignore raise d_TypeMismatchError( f"Cannot assign {val.public_type} to {self.public_type}")