Пример #1
0
    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
Пример #2
0
 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
Пример #3
0
 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")
Пример #4
0
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}"
            )
Пример #5
0
    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
            )
Пример #6
0
    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
Пример #7
0
 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))
Пример #8
0
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)
Пример #9
0
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}")