def _gen_array_iter_type(elem_tp): t = larc_token.make_fake_token_name("ArrayIter").copy_on_pos( elem_tp.token) #在当前位置弄个假token iter_tp = _Type((t, t.value), None, None, module_name="__builtins") iter_tp.gtp_list = [elem_tp] #设置elem_tp为泛型参数 iter_tp.get_coi() #触发一下,这里也是check里面做的流程 iter_tp._set_is_checked() #锁住 return iter_tp
def gen_internal_iter_type(elem_tp, t): t = larc_token.make_fake_token_name("_Iter").copy_on_pos(t) #在当前位置弄个假token iter_tp = _Type((t, t.value), None, None, module_name="__builtins") iter_tp.gtp_list = [elem_tp] #设置elem_tp为泛型参数 iter_tp.get_coi() #触发一下,这里也是check里面做的流程 iter_tp._set_is_checked() #锁住 larc_module.check_new_ginst_during_compile() return iter_tp
def _gen_arr_type(elem_tp): t = larc_token.make_fake_token_name("Arr").copy_on_pos(elem_tp.token) #在当前位置弄个假token arr_tp = _Type((t, t.value), None, None, module_name = "__array") arr_tp.gtp_list = [elem_tp] #设置elem_tp为泛型参数 arr_tp.get_coi() #触发一下,这里也是check里面做的流程 arr_tp._set_is_checked() #锁住 #这里暂时不需要check_new_ginst_during_compile,因为调用这个函数的时候要么arr已经存在了,要么是在其他type的check流程中 return arr_tp
def gen_internal_iter_type(elem_tp, t): t = larc_token.make_fake_token_name("_Iter").copy_on_pos(t) #在当前位置弄个假token iter_tp = _Type((t, t.value), None, None, module_name = "__builtins") iter_tp.gtp_list = [elem_tp] #设置elem_tp为泛型参数 iter_tp.get_coi() #触发一下,这里也是check里面做的流程 iter_tp._set_is_checked() #锁住 larc_module.check_new_ginst_during_compile() return iter_tp
def gen_type_from_cls(cls): tp = _Type((larc_token.make_fake_token_name(cls.name), cls.name), None, None, module_name = cls.module.name) if cls.is_gcls_inst: tp.gtp_list = list(cls.gtp_map.itervalues()) #这个类型没必要check了,校验一下get_coi正常就直接返回 tp._set_is_checked() assert tp.get_coi() is cls return tp
def _gen_arr_type(elem_tp): t = larc_token.make_fake_token_name("Arr").copy_on_pos( elem_tp.token) #在当前位置弄个假token arr_tp = _Type((t, t.value), None, None, module_name="__array") arr_tp.gtp_list = [elem_tp] #设置elem_tp为泛型参数 arr_tp.get_coi() #触发一下,这里也是check里面做的流程 arr_tp._set_is_checked() #锁住 #这里暂时不需要check_new_ginst_during_compile,因为调用这个函数的时候要么arr已经存在了,要么是在其他type的check流程中 return arr_tp
def gen_closure_type(closure): tp = _Type((larc_token.make_fake_token_name(closure.name), closure.name), None, None, module_name=closure.module.name, is_closure=True) #这个类型没必要check了,校验一下get_coi正常就直接返回 tp._set_is_checked() assert tp.get_coi() is closure return tp
def gen_type_from_cls(cls): tp = _Type((larc_token.make_fake_token_name(cls.name), cls.name), None, None, module_name=cls.module.name) if cls.is_gcls_inst: tp.gtp_list = list(cls.gtp_map.itervalues()) #这个类型没必要check了,校验一下get_coi正常就直接返回 tp._set_is_checked() assert tp.get_coi() is cls return tp
def parse(self, var_map_stk, need_type): start_token = self.token_list.peek() parse_stk = _ParseStk(start_token, self.curr_module, self.cls, self.fom) while True: t = self.token_list.pop() if t.is_sym and t.value in ("~", "!", "+", "-"): #单目运算 if t.value == "+": op = "pos" elif t.value == "-": op = "neg" else: op = t.value parse_stk.push_op(op) continue if t.is_sym("("): #子表达式 parse_stk.push_expr(self.parse(var_map_stk, None)) self.token_list.pop_sym(")") elif t.is_reserved("cast"): self.token_list.pop_sym("<") t = self.token_list.peek() tp = larc_type.try_parse_type( self.token_list, self.curr_module, self.dep_module_map, self.gtp_map, var_map_stk, used_dep_module_set=self.used_dep_module_set) if tp is None: t.syntax_err("需要类型") if tp == larc_type.VOID_TYPE: t.syntax_err("无效的类型强转:不能转为void类型") self.token_list.pop_sym(">") self.token_list.pop_sym("(") expr = self.parse(var_map_stk, None) self.token_list.pop_sym(")") if not tp.can_force_convert_from(expr.type): t.syntax_err("无效的强制类型转换:‘%s’到‘%s’" % (expr.type, tp)) parse_stk.push_expr(_Expr("force_convert", (tp, expr), tp)) elif t.is_name: if t.value in self.dep_module_map: m = larc_module.module_map[self.dep_module_map[t.value]] self.token_list.pop_sym(".") t, name = self.token_list.pop_name() expr = self._parse_func_or_global_var( m, (t, name), var_map_stk) parse_stk.push_expr(expr) else: for var_map in reversed(var_map_stk): if t.value in var_map: #局部变量 tp = var_map[t.value] if tp is None: #初始化变量的时候引用了变量本身 t.syntax_err("变量'%s'在初始化前使用" % (t.value)) parse_stk.push_expr(_Expr("local_var", t.value, tp)) break else: #当前模块或builtin模块 for m in self.curr_module, larc_module.builtins_module: if m.has_func(t.value) or m.has_global_var( t.value): expr = self._parse_func_or_global_var( m, (t, t.value), var_map_stk) parse_stk.push_expr(expr) break else: t.syntax_err("未定义的标识符'%s'" % t.value) elif t.is_literal: assert t.type.startswith("literal_") if t.type == "literal_int": #int字面量需要特殊处理 tp = larc_type.LITERAL_INT_TYPE else: tp = eval("larc_type.%s_TYPE" % t.type[8:].upper()) e = _Expr("literal", t, tp) if t.type == "literal_str" and self.token_list.peek().is_sym( ".") and self.token_list.peek(1).is_sym("("): #字符串常量的format语法 fmt, expr_list = self._parse_str_format(var_map_stk, t) e = _Expr("str_format", (fmt, expr_list), larc_type.STR_TYPE) parse_stk.push_expr(e) elif t.is_reserved("new"): base_type = larc_type.parse_type(self.token_list, self.dep_module_map, non_array=True) base_type.check(self.curr_module, self.gtp_map, self.used_dep_module_set) larc_module.check_new_ginst_during_compile() new_token = t t = self.token_list.pop() if t.is_sym("("): t = self.token_list.peek() expr_list = self._parse_expr_list(var_map_stk) is_new_cls = False if not (base_type.is_array or base_type.token.is_reserved): new_coi = base_type.get_coi() if new_coi.is_cls or new_coi.is_gcls_inst: if new_coi.module is not self.curr_module and "public" not in new_coi.construct_method.decr_set: base_type.token.syntax_err( "无法创建'%s'的实例:对构造方法无访问权限" % new_coi) self._make_expr_list_match_arg_map( t, expr_list, new_coi.construct_method.arg_map) parse_stk.push_expr( _Expr("new", expr_list, base_type)) is_new_cls = True if not is_new_cls: #对数组、基础类型、闭包或接口使用new语法 new_token.syntax_err("不能对类型'%s'使用new语法" % base_type) elif t.is_sym("["): if base_type.is_void: t.syntax_err("无法创建void数组") if self.token_list.peek().is_sym("]"): #通过初始化列表创建数组 self.token_list.pop_sym("]") init_list_type = base_type.to_array_type(1) while self.token_list.peek().is_sym("["): self.token_list.pop_sym("[") self.token_list.pop_sym("]") init_list_type = init_list_type.to_array_type(1) larc_module.check_new_ginst_during_compile() parse_stk.push_expr( self._parse_init_list(var_map_stk, init_list_type)) else: #创建普通数组 size_list = [ self.parse(var_map_stk, larc_type.VALID_ARRAY_SIZE_TYPES) ] init_dim_count = 1 self.token_list.pop_sym("]") while self.token_list.peek().is_sym("["): self.token_list.pop_sym("[") t = self.token_list.peek() if t.is_sym("]"): size_list.append(None) self.token_list.pop_sym("]") continue if size_list[-1] is None: t.syntax_err("需要']'") size_list.append( self.parse(var_map_stk, larc_type.VALID_ARRAY_SIZE_TYPES)) init_dim_count += 1 self.token_list.pop_sym("]") array_base_type = base_type while array_base_type.is_array: array_base_type = array_base_type.to_elem_type() size_list.append(None) array_type = array_base_type.to_array_type( len(size_list)) larc_module.check_new_ginst_during_compile() parse_stk.push_expr( _Expr("new_array", (array_base_type, size_list), array_type)) elif t.is_sym("{"): new_coi = None if base_type.is_coi_type: coi = base_type.get_coi() if coi.is_cls or coi.is_gcls_inst: new_coi = coi if new_coi is None: base_type.token.syntax_err("'%s'不是类,不能按属性初始化" % base_type) attr_map = new_coi.get_initable_attr_map( base_type.token, self.curr_module) attr_init_map = larc_common.OrderedDict() #根据下面两个token判定是否指定属性名来初始化 revert_idx = self.token_list.i t1 = self.token_list.pop() t2 = self.token_list.pop() self.token_list.revert(revert_idx) is_initing_by_attr_name = t1.is_name and t2.is_sym(":") while True: t = self.token_list.peek() if t.is_sym("}"): self.token_list.pop_sym() break if is_initing_by_attr_name: t, name = self.token_list.pop_name() if name not in attr_map: t.syntax_err("类'%s'没有属性'%s'或不可初始化它" % (base_type, name)) if name in attr_init_map: t.syntax_err("属性'%s'重复初始化" % (name)) self.token_list.pop_sym(":") else: key_idx = len(attr_init_map) if key_idx >= len(attr_map): t.syntax_err("过多的初始化值") name = attr_map.key_at(key_idx) attr_init_map[name] = self.parse( var_map_stk, attr_map[name]) t = self.token_list.peek() if not (t.is_sym and t.value in ("}", ",")): t.syntax_err("需要','或'}'") if t.value == ",": self.token_list.pop_sym() for name, tp in attr_map.iteritems(): if name not in attr_init_map: attr_init_map[name] = _Expr( "default_value", tp, tp) parse_stk.push_expr( _Expr("new_obj_init_by_attr", attr_init_map, base_type)) else: t.syntax_err("需要'('或'['") elif t.is_reserved("this"): if self.cls is None: t.syntax_err("'this'只能用于方法中") parse_stk.push_expr( _Expr("this", t, larc_type.gen_type_from_cls(self.cls))) elif t.is_sym("["): #闭包对象 if self.fom is None: t.syntax_err("闭包只能用于函数或方法中") is_simple_callable = False next_t = self.token_list.pop() if next_t.is_sym("-"): self.token_list.pop_sym("]") is_simple_callable = True elif not next_t.is_sym("]"): next_t.syntax_err("闭包表达式语法错误") closure_token = larc_token.make_fake_token_name( "closure").copy_on_pos(t) closure = self.curr_module.new_closure(self.file_name, closure_token, self.cls, self.gtp_map, var_map_stk) closure.parse(self.token_list, is_simple_callable) self.new_closure_hook_stk[-1](closure) parse_stk.push_expr( _Expr("closure", closure, larc_type.gen_closure_type(closure))) else: t.syntax_err("非法的表达式") assert parse_stk.stk #解析后缀运算符 while self.token_list: t = self.token_list.pop() if t.is_sym("["): is_slice = False if self.token_list.peek().is_sym(":"): expr = None is_slice = True else: expr = self.parse(var_map_stk, larc_type.VALID_ARRAY_IDX_TYPES) if self.token_list.peek().is_sym(":"): self.token_list.pop_sym(":") if self.token_list.peek().is_sym("]"): slice_end_expr = None else: slice_end_expr = self.parse( var_map_stk, larc_type.VALID_ARRAY_IDX_TYPES) is_slice = True self.token_list.pop_sym("]") array_expr = parse_stk.stk[-1] if not array_expr.type.is_array: t.syntax_err("'%s'非数组,不能进行下标或分片运算" % array_expr.type) if is_slice: parse_stk.stk[-1] = _Expr( "[:]", [array_expr, expr, slice_end_expr], array_expr.type) else: parse_stk.stk[-1] = _Expr( "[]", [array_expr, expr], array_expr.type.to_elem_type()) elif t.is_sym("."): t, name = self.token_list.pop_name() obj = parse_stk.stk[-1] if obj.type.is_array: #数组 method = larc_type.get_array_method(obj.type, name) if method is None: t.syntax_err("数组没有方法'%s'" % name) self.token_list.pop_sym("(") t = self.token_list.peek() expr_list = self._parse_expr_list(var_map_stk) self._make_expr_list_match_arg_map( t, expr_list, method.arg_map) parse_stk.stk[-1] = _Expr( "call_array.method", (parse_stk.stk[-1], method, expr_list), method.type) else: if obj.type.token.is_reserved: t.syntax_err("不能对基础类型取属性或调用方法") obj_coi = obj.type.get_coi() method, attr = obj_coi.get_method_or_attr(name, t) if method is not None: assert attr is None self.token_list.pop_sym("(") if method.module is not self.curr_module and "public" not in method.decr_set: t.syntax_err("无法使用方法'%s':没有权限" % method) t = self.token_list.peek() expr_list = self._parse_expr_list(var_map_stk) self._make_expr_list_match_arg_map( t, expr_list, method.arg_map) parse_stk.stk[-1] = _Expr( "call_method", (parse_stk.stk[-1], method, expr_list), method.type) else: assert attr is not None and method is None if attr.module is not self.curr_module and "public" not in attr.decr_set: t.syntax_err("无法访问属性'%s':没有权限" % attr) parse_stk.stk[-1] = _Expr( ".", (parse_stk.stk[-1], attr), attr.type) else: self.token_list.revert() break if _is_expr_end(self.token_list.peek()): #表达式结束 break #状态:解析普通二元运算符 t = self.token_list.pop() if (t.is_sym and t.value in _BINOCULAR_OP_SET) or ( t.is_reserved and t.value in ("if", "else")): #二、三元运算 parse_stk.push_op(t.value) else: t.syntax_err("需要二元或三元运算符") expr = parse_stk.finish() expr_pos_info = expr.pos_info #保存一下pos info if need_type is not None: if isinstance(need_type, (tuple, list)): need_type_list = list(need_type) else: need_type_list = [need_type] for need_type in need_type_list: if need_type == expr.type: break if expr.op == "literal" and expr.type == larc_type.LITERAL_INT_TYPE and need_type.is_number_type: e = _convert_literal_int_expr(expr, need_type) if e is None: continue expr = e if expr is not None and need_type.can_convert_from(expr.type): if need_type != expr.type: expr = _Expr("force_convert", (need_type, expr), need_type) break else: if len(need_type_list) == 1: start_token.syntax_err("表达式(类型'%s')无法隐式转换为类型'%s'" % (expr.type, need_type_list[0])) else: start_token.syntax_err("表达式(类型'%s')无法隐式转换为类型%s其中任意一个" % (expr.type, str(need_type_list))) expr.pos_info = expr_pos_info #expr可能根据need_tyep修改了,恢复一下pos info return expr
return True #接下来就是正反向都无法转换的情形,这时候还能强转的就只能是number类型之间的了 if self.is_number_type and type.is_number_type: return True #其余情况不能强转 return False #生成默认类型对象,其中literal_int和nil类型内部使用,String类型虽然是class,但由于代码中有str literal,也需预先生成 for _tp in _BASE_TYPE_LIST + ("literal_int", "nil"): exec '%s_TYPE = _Type((larc_token.make_fake_token_reserved("%s"), "%s"), None, None)' % ( _tp.upper(), _tp, _tp) exec "%s_TYPE._set_is_checked()" % _tp.upper() STR_TYPE = _Type((larc_token.make_fake_token_name("String"), "String"), None, None, module_name="__builtins") STR_TYPE._set_is_checked() #所有整数类型都可以作为数组下标 VALID_ARRAY_IDX_TYPES = [SCHAR_TYPE, CHAR_TYPE] for _tp in "short", "int", "long": VALID_ARRAY_IDX_TYPES.append(eval("%s_TYPE" % _tp.upper())) VALID_ARRAY_IDX_TYPES.append(eval("U%s_TYPE" % _tp.upper())) del _tp def parse_type(token_list, dep_module_map, is_ref=False, non_array=False): if is_ref:
#其余情况不能强转 return False def clear_is_ref(self): self._unfreeze() self.is_ref = False self._freeze() #生成默认类型对象,其中literal_int和nil类型内部使用,String类型虽然是class,但由于代码中有str literal,也需预先生成 for _tp in _BASE_TYPE_LIST + ("literal_int", "nil"): exec '%s_TYPE = _Type((larc_token.make_fake_token_reserved("%s"), "%s"), None, None)' % ( _tp.upper(), _tp, _tp) exec "%s_TYPE._set_is_checked()" % _tp.upper() GO_ANY_INTF_TYPE = _Type((larc_token.make_fake_token_name("GoAny"), "GoAny"), None, None, module_name="__builtins") GO_ANY_INTF_TYPE._set_is_checked() ANY_INTF_TYPE = _Type((larc_token.make_fake_token_name("Any"), "Any"), None, None, module_name="__builtins") ANY_INTF_TYPE._set_is_checked() STR_TYPE = _Type((larc_token.make_fake_token_name("String"), "String"), None, None, module_name="__builtins") STR_TYPE._set_is_checked() NIL_REF_TYPE = _Type((larc_token.make_fake_token_name("nil_ref"), "nil_ref"),
return True #接下来就是正反向都无法转换的情形,这时候还能强转的就只能是number类型之间的了 if self.is_number_type and type.is_number_type: return True #其余情况不能强转 return False #生成默认类型对象,其中literal_int和nil类型内部使用,String类型虽然是class,但由于代码中有str literal,也需预先生成 for _tp in _BASE_TYPE_LIST + ("literal_int", "nil"): exec '%s_TYPE = _Type((larc_token.make_fake_token_reserved("%s"), "%s"), None, None)' % ( _tp.upper(), _tp, _tp) exec "%s_TYPE._set_is_checked()" % _tp.upper() ANY_INTF_TYPE = _Type((larc_token.make_fake_token_name("Any"), "Any"), None, None, module_name="__builtins") ANY_INTF_TYPE._set_is_checked() STR_TYPE = _Type((larc_token.make_fake_token_name("String"), "String"), None, None, module_name="__builtins") STR_TYPE._set_is_checked() #所有整数类型都可以作为数组下标 VALID_ARRAY_IDX_TYPES = [SCHAR_TYPE, CHAR_TYPE] for _tp in "short", "int", "long": VALID_ARRAY_IDX_TYPES.append(eval("%s_TYPE" % _tp.upper())) VALID_ARRAY_IDX_TYPES.append(eval("U%s_TYPE" % _tp.upper()))
def gen_closure_type(closure): tp = _Type((larc_token.make_fake_token_name(closure.name), closure.name), None, None, module_name = closure.module.name, is_closure = True) #这个类型没必要check了,校验一下get_coi正常就直接返回 tp._set_is_checked() assert tp.get_coi() is closure return tp
if not type.is_literal_int and type.can_convert_from(self): #能反向隐式转换,则可以强转 return True #接下来就是正反向都无法转换的情形,这时候还能强转的就只能是number类型之间的了 if self.is_number_type and type.is_number_type: return True #其余情况不能强转 return False #生成默认类型对象,其中literal_int和nil类型内部使用,String类型虽然是class,但由于代码中有str literal,也需预先生成 for _tp in _BASE_TYPE_LIST + ("literal_int", "nil"): exec '%s_TYPE = _Type((larc_token.make_fake_token_reserved("%s"), "%s"), None, None)' % (_tp.upper(), _tp, _tp) exec "%s_TYPE._set_is_checked()" % _tp.upper() ANY_INTF_TYPE = _Type((larc_token.make_fake_token_name("Any"), "Any"), None, None, module_name = "__builtins") ANY_INTF_TYPE._set_is_checked() STR_TYPE = _Type((larc_token.make_fake_token_name("String"), "String"), None, None, module_name = "__builtins") STR_TYPE._set_is_checked() #所有整数类型都可以作为数组下标 VALID_ARRAY_IDX_TYPES = [SCHAR_TYPE, CHAR_TYPE] for _tp in "short", "int", "long": VALID_ARRAY_IDX_TYPES.append(eval("%s_TYPE" % _tp.upper())) VALID_ARRAY_IDX_TYPES.append(eval("U%s_TYPE" % _tp.upper())) del _tp def is_type(tp): return isinstance(tp, _Type) def parse_type(token_list, dep_module_map, is_ref = False, non_array = False):
def parse(self, var_map_stk, need_type): start_token = self.token_list.peek() parse_stk = _ParseStk(start_token, self.curr_module, self.cls, self.fom) while True: t = self.token_list.pop() if t.is_sym and t.value in ("~", "!", "+", "-"): #单目运算 if t.value == "+": op = "pos" elif t.value == "-": op = "neg" else: op = t.value parse_stk.push_op(op) continue if t.is_sym("("): tp = larc_type.try_parse_type(self.token_list, self.curr_module, self.dep_module_map, self.gtp_map, var_map_stk, used_dep_module_set = self.used_dep_module_set) if tp is not None: #类型强转 if tp == larc_type.VOID_TYPE: t.syntax_err("无效的类型强转:不能转为void类型") self.token_list.pop_sym(")") parse_stk.push_op("force_convert", tp) continue #子表达式 parse_stk.push_expr(self.parse(var_map_stk, None)) self.token_list.pop_sym(")") elif t.is_name: if t.value in self.dep_module_map: m = larc_module.module_map[self.dep_module_map[t.value]] self.token_list.pop_sym(".") t, name = self.token_list.pop_name() expr = self._parse_func_or_global_var(m, (t, name), var_map_stk) parse_stk.push_expr(expr) else: for var_map in reversed(var_map_stk): if t.value in var_map: #局部变量 tp = var_map[t.value] if tp is None: #初始化变量的时候引用了变量本身 t.syntax_err("变量'%s'在初始化前使用" % (t.value)) parse_stk.push_expr(_Expr("local_var", t.value, tp)) break else: #当前模块或builtin模块 for m in self.curr_module, larc_module.builtins_module: if m.has_func(t.value) or m.has_global_var(t.value): expr = self._parse_func_or_global_var(m, (t, t.value), var_map_stk) parse_stk.push_expr(expr) break else: t.syntax_err("未定义的标识符'%s'" % t.value) elif t.is_literal: assert t.type.startswith("literal_") if t.type == "literal_int": #int字面量需要特殊处理 tp = larc_type.LITERAL_INT_TYPE else: tp = eval("larc_type.%s_TYPE" % t.type[8 :].upper()) e = _Expr("literal", t, tp) if t.type == "literal_str" and self.token_list.peek().is_sym(".") and self.token_list.peek(1).is_sym("("): #字符串常量的format语法 fmt, expr_list = self._parse_str_format(var_map_stk, t) e = _Expr("str_format", (fmt, expr_list), larc_type.STR_TYPE) parse_stk.push_expr(e) elif t.is_reserved("new"): base_type = larc_type.parse_type(self.token_list, self.dep_module_map, non_array = True) base_type.check(self.curr_module, self.gtp_map, self.used_dep_module_set) larc_module.check_new_ginst_during_compile() new_token = t t = self.token_list.pop() if t.is_sym("("): t = self.token_list.peek() expr_list = self._parse_expr_list(var_map_stk) is_new_cls = False if not (base_type.is_array or base_type.token.is_reserved): new_coi = base_type.get_coi() if new_coi.is_cls or new_coi.is_gcls_inst: if new_coi.module is not self.curr_module and "public" not in new_coi.construct_method.decr_set: base_type.token.syntax_err("无法创建'%s'的实例:对构造方法无访问权限" % new_coi) self._make_expr_list_match_arg_map(t, expr_list, new_coi.construct_method.arg_map) parse_stk.push_expr(_Expr("new", expr_list, base_type)) is_new_cls = True if not is_new_cls: #对数组、基础类型或接口使用new语法 new_token.syntax_err("不能对类型'%s'使用new语法" % base_type) elif t.is_sym("["): if base_type.is_void: t.syntax_err("无法创建void数组") if self.token_list.peek().is_sym("]"): #通过初始化列表创建数组 self.token_list.pop_sym("]") init_list_type = base_type.to_array_type(1) while self.token_list.peek().is_sym("["): self.token_list.pop_sym("[") self.token_list.pop_sym("]") init_list_type = init_list_type.to_array_type(1) larc_module.check_new_ginst_during_compile() parse_stk.push_expr(self._parse_init_list(var_map_stk, init_list_type)) else: #创建普通数组 size_list = [self.parse(var_map_stk, larc_type.VALID_ARRAY_IDX_TYPES)] init_dim_count = 1 self.token_list.pop_sym("]") while self.token_list.peek().is_sym("["): self.token_list.pop_sym("[") t = self.token_list.peek() if t.is_sym("]"): size_list.append(None) self.token_list.pop_sym("]") continue if size_list[-1] is None: t.syntax_err("需要']'") size_list.append(self.parse(var_map_stk, larc_type.VALID_ARRAY_IDX_TYPES)) init_dim_count += 1 self.token_list.pop_sym("]") array_base_type = base_type while array_base_type.is_array: array_base_type = array_base_type.to_elem_type() size_list.append(None) array_type = array_base_type.to_array_type(len(size_list)) larc_module.check_new_ginst_during_compile() parse_stk.push_expr(_Expr("new_array", (array_base_type, size_list), array_type)) elif t.is_sym("{"): new_coi = None if base_type.is_coi_type: coi = base_type.get_coi() if coi.is_cls or coi.is_gcls_inst: new_coi = coi if new_coi is None: base_type.token.syntax_err("'%s'不是类,不能按属性初始化") attr_map = new_coi.get_initable_attr_map(base_type.token) attr_init_map = larc_common.OrderedDict() while True: t = self.token_list.peek() if t.is_sym("}"): self.token_list.pop_sym() break t, name = self.token_list.pop_name() if name not in attr_map: t.syntax_err("类'%s'没有属性'%s'或不可初始化它" % (base_type, name)) if name in attr_init_map: t.syntax_err("属性'%s'重复初始化" % (name)) self.token_list.pop_sym(":") attr_init_map[name] = self.parse(var_map_stk, attr_map[name]) t = self.token_list.peek() if not (t.is_sym and t.value in ("}", ",")): t.syntax_err("需要','或'}'") if t.value == ",": self.token_list.pop_sym() for name, tp in attr_map.iteritems(): if name not in attr_init_map: attr_init_map[name] = _Expr("default_value", tp, tp) parse_stk.push_expr(_Expr("new_obj_init_by_attr", attr_init_map, base_type)) else: t.syntax_err("需要'('或'['") elif t.is_reserved("this"): if self.cls is None: t.syntax_err("'this'只能用于方法中") parse_stk.push_expr(_Expr("this", t, larc_type.gen_type_from_cls(self.cls))) elif t.is_sym("["): #闭包对象 if self.fom is None: t.syntax_err("闭包只能用于函数或方法中") self.token_list.pop_sym("]") closure_token = larc_token.make_fake_token_name("closure").copy_on_pos(t) closure = self.curr_module.new_closure(self.file_name, closure_token, self.cls, self.gtp_map, var_map_stk) closure.parse(self.token_list) self.new_closure_hook_stk[-1](closure) parse_stk.push_expr(_Expr("closure", closure, larc_type.gen_closure_type(closure))) else: t.syntax_err("非法的表达式") assert parse_stk.stk #解析后缀运算符 while self.token_list: t = self.token_list.pop() if t.is_sym("["): is_slice = False if self.token_list.peek().is_sym(":"): expr = None is_slice = True else: expr = self.parse(var_map_stk, larc_type.VALID_ARRAY_IDX_TYPES) if self.token_list.peek().is_sym(":"): self.token_list.pop_sym(":") if self.token_list.peek().is_sym("]"): slice_end_expr = None else: slice_end_expr = self.parse(var_map_stk, larc_type.VALID_ARRAY_IDX_TYPES) is_slice = True self.token_list.pop_sym("]") array_expr = parse_stk.stk[-1] if not array_expr.type.is_array: t.syntax_err("'%s'非数组,不能进行下标或分片运算" % array_expr.type) if is_slice: parse_stk.stk[-1] = _Expr("[:]", [array_expr, expr, slice_end_expr], array_expr.type) else: parse_stk.stk[-1] = _Expr("[]", [array_expr, expr], array_expr.type.to_elem_type()) elif t.is_sym("."): t, name = self.token_list.pop_name() obj = parse_stk.stk[-1] if obj.type.is_array: #数组 method = larc_type.get_array_method(obj.type, name) if method is None: t.syntax_err("数组没有方法'%s'" % name) self.token_list.pop_sym("(") t = self.token_list.peek() expr_list = self._parse_expr_list(var_map_stk) self._make_expr_list_match_arg_map(t, expr_list, method.arg_map) parse_stk.stk[-1] = _Expr("call_array.method", (parse_stk.stk[-1], method, expr_list), method.type) else: if obj.type.token.is_reserved: t.syntax_err("不能对基础类型取属性或调用方法") obj_coi = obj.type.get_coi() method, attr = obj_coi.get_method_or_attr(name, t) if method is not None: assert attr is None self.token_list.pop_sym("(") if method.module is not self.curr_module and "public" not in method.decr_set: t.syntax_err("无法使用方法'%s':没有权限" % method) t = self.token_list.peek() expr_list = self._parse_expr_list(var_map_stk) self._make_expr_list_match_arg_map(t, expr_list, method.arg_map) parse_stk.stk[-1] = _Expr("call_method", (parse_stk.stk[-1], method, expr_list), method.type) else: assert attr is not None and method is None if attr.module is not self.curr_module and "public" not in attr.decr_set: t.syntax_err("无法访问属性'%s':没有权限" % attr) parse_stk.stk[-1] = _Expr(".", (parse_stk.stk[-1], attr), attr.type) else: self.token_list.revert() break if _is_expr_end(self.token_list.peek()): #表达式结束 break #状态:解析普通二元运算符 t = self.token_list.pop() if t.is_sym and t.value in _BINOCULAR_OP_SET: #二元运算 parse_stk.push_op(t.value) else: t.syntax_err("需要二元运算符") expr = parse_stk.finish() expr_pos_info = expr.pos_info #保存一下pos info if need_type is not None: if isinstance(need_type, (tuple, list)): need_type_list = list(need_type) else: need_type_list = [need_type] for need_type in need_type_list: if need_type == expr.type: break if expr.op == "literal" and expr.type == larc_type.LITERAL_INT_TYPE and need_type.is_number_type: e = _convert_literal_int_expr(expr, need_type) if e is None: continue expr = e if expr is not None and need_type.can_convert_from(expr.type): if need_type != expr.type: expr = _Expr("force_convert", (need_type, expr), need_type) break else: if len(need_type_list) == 1: start_token.syntax_err("表达式(类型'%s')无法隐式转换为类型'%s'" % (expr.type, need_type_list[0])) else: start_token.syntax_err("表达式(类型'%s')无法隐式转换为类型%s其中任意一个" % (expr.type, str(need_type_list))) expr.pos_info = expr_pos_info #expr可能根据need_tyep修改了,恢复一下pos info return expr