private SyntaxTree.ident ConvertOperatorNameToIdent(SyntaxTree.ident opname) { if (opname is SyntaxTree.operator_name_ident) { SyntaxTree.ident id = new SyntaxTree.ident(name_reflector.get_name((opname as SyntaxTree.operator_name_ident).operator_type)); id.source_context = opname.source_context; return id; } return opname; }
private SyntaxTree.procedure_call ConvertEventOperationToProcedureCall(SyntaxTree.assign _assign) { SyntaxTree.ident event_name = _assign.to as SyntaxTree.ident; SyntaxTree.dot_node dot = _assign.to as SyntaxTree.dot_node; if (dot != null) event_name = dot.right as SyntaxTree.ident; if (event_name == null) AddError(new EventNameExpected(get_location(_assign.to))); string format; if (_assign.operator_type == PascalABCCompiler.SyntaxTree.Operators.AssignmentSubtraction) format = compiler_string_consts.event_remove_method_nameformat; else format = compiler_string_consts.event_add_method_nameformat; SyntaxTree.ident add_name = new SyntaxTree.ident(string.Format(format, event_name.name)); add_name.source_context = event_name.source_context; if (dot != null) dot.right = add_name; SyntaxTree.expression_list exprlist = new SyntaxTree.expression_list(); exprlist.expressions.Add(_assign.from); exprlist.source_context = _assign.to.source_context; SyntaxTree.method_call add_methcall = new SyntaxTree.method_call(exprlist); if (dot != null) add_methcall.dereferencing_value = dot; else add_methcall.dereferencing_value = add_name; add_methcall.source_context = _assign.source_context; SyntaxTree.procedure_call add_proccall = new SyntaxTree.procedure_call(add_methcall); add_proccall.source_context = _assign.source_context; return add_proccall; }
//ssyy изменил этот метод из-за изменения концепции конструкторов public override void visit(SyntaxTree.constructor _constructor) { if (context.converting_block() == block_type.type_block) { if (context.converted_type.IsInterface) { AddError(new ConstructorInInterface(get_location(_constructor))); } /*if (!context.converted_type.is_class) { throw new ConstructorNotInClass(get_location(_constructor)); }*/ } else if (!(context.converting_block() == block_type.namespace_block && _constructor.name != null && _constructor.name.class_name != null)) { AddError(get_location(_constructor), "CONSTRUCTOR_NOT_IN_CLASS"); } convertion_data_and_alghoritms.check_node_parser_error(_constructor.name); if (_constructor.name == null) { SyntaxTree.ident name = new SyntaxTree.ident(compiler_string_consts.default_constructor_name); _constructor.name = new PascalABCCompiler.SyntaxTree.method_name(null, null, name, null); _constructor.name.source_context = _constructor.name.meth_name.source_context = _constructor.source_context; } if (_constructor.name.meth_name.name.ToLower() != compiler_string_consts.default_constructor_name) AddError(get_location(_constructor.name), "CONSTRUCTOR_CAN_HAVE_ONLY_{0}_NAME", compiler_string_consts.default_constructor_name); if ((_constructor.name.class_name == null) && (context.converting_block() != block_type.type_block)) { AddError(get_location(_constructor.name), "ONLY_CONSTRUCTOR_OF_TYPE_ALLOWED"); } foreach (SyntaxTree.procedure_attribute att in _constructor.proc_attributes.proc_attributes) { if (att.attribute_type == SyntaxTree.proc_attribute.attr_virtual) { AddError(get_location(att), "CONSTRUCTOR_CAN_NOT_BE_VIRTUAL"); } else if (att.attribute_type == SyntaxTree.proc_attribute.attr_override) { AddError(get_location(att), "CONSTRUCTOR_CAN_NOT_BE_OVERRIDE"); } else if (att.attribute_type == SyntaxTree.proc_attribute.attr_abstract) { AddError(get_location(att), "CONSTRUCTOR_CANNOT_BE_ABSTRACT"); } } if (_constructor.class_keyword) { SyntaxTree.procedure_attribute pa = new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static); pa.source_context = _constructor.source_context; _constructor.proc_attributes.proc_attributes.Add(pa); } foreach (SyntaxTree.procedure_attribute att in _constructor.proc_attributes.proc_attributes) { if (att.attribute_type == SyntaxTree.proc_attribute.attr_static) { //Это статический конструктор if (_constructor.parameters != null) { AddError(get_location(_constructor.name), "STATIC_CONSTRUCTOR_MUST_BE_PARAMETERLESS"); } _constructor.name.meth_name.name = compiler_string_consts.static_ctor_prefix + _constructor.name.meth_name.name; visit_procedure_header(_constructor); if (context.top_function != null) { (context.top_function as common_method_node).is_constructor = true; (context.top_function as common_method_node).cont_type.static_constr = context.top_function as common_method_node; } return; } } if (context.converting_block() == block_type.type_block) { //Нужно для генерации унаследованных конструкторов context.converted_type.has_user_defined_constructor = true; //Нужно для генерации конструктора по умолчанию if (_constructor.parameters == null || _constructor.parameters.params_list[0].inital_value != null) { context.converted_type.has_default_constructor = true; } } visit_procedure_header(_constructor); if (context.top_function == null) { return; } common_method_node cmn = context.top_function as common_method_node; if (cmn == null) { throw new CompilerInternalError("Constructor is not common_method_node."); } context.allow_inherited_ctor_call = true; cmn.is_constructor = true; cmn.return_value_type = context.converted_type; }
public MemberIsNotDeclaredInNamespace(SyntaxTree.ident id, location loc, namespace_node nn) { _id = id; _loc = loc; _nn = nn; }
public MemberIsNotDeclaredInType(SyntaxTree.ident id, location loc, type_node tn) { _id = id; _loc = loc; _tn = tn; }
public procedure_definition lambda(function_lambda_definition _function_lambda_definition) { SyntaxTree.procedure_definition _func_def = new PascalABCCompiler.SyntaxTree.procedure_definition(); SyntaxTree.method_name _method_name1 = new SyntaxTree.method_name(null, new SyntaxTree.ident(_function_lambda_definition.lambda_name), null); SyntaxTree.function_header _function_header1 = new SyntaxTree.function_header(); object rt1 = new object(); _function_header1.name = _method_name1; SyntaxTree.formal_parametres fps = new PascalABCCompiler.SyntaxTree.formal_parametres(); _function_header1.parametres = _function_lambda_definition.formal_parametres;//fps; SyntaxTree.named_type_reference _named_type_reference = new SyntaxTree.named_type_reference(); SyntaxTree.ident idtype = new SyntaxTree.ident("datatype"); _named_type_reference.source_context = idtype.source_context; _named_type_reference.names.Add(idtype); rt1 = _named_type_reference; _function_header1.return_type = (SyntaxTree.type_definition)_named_type_reference; _function_header1.of_object = false; _function_header1.class_keyword = false; SyntaxTree.block _block1 = new SyntaxTree.block(null, null); SyntaxTree.statement_list sl1 = new SyntaxTree.statement_list(); sl1.subnodes.Add(_function_lambda_definition.proc_body); _block1.program_code = sl1; _func_def.proc_header = _function_header1; _func_def.proc_body = (SyntaxTree.proc_block)_block1; _function_lambda_definition.proc_definition = _func_def; return _func_def; }
private static SyntaxTree.expression ConvertConstant(SemanticTree.IConstantNode value) { if (value is bool_const_node) return new SyntaxTree.ident((value as bool_const_node).constant_value ? "true" : "false"); else if (value is null_const_node) return new SyntaxTree.nil_const(); else if (value is byte_const_node) return new SyntaxTree.int32_const((value as byte_const_node).constant_value); else if (value is char_const_node) return new SyntaxTree.char_const((value as char_const_node).constant_value); else if (value is double_const_node) return new SyntaxTree.double_const((value as double_const_node).constant_value); else if (value is float_const_node) return new SyntaxTree.double_const((value as float_const_node).constant_value); else if (value is int_const_node) return new SyntaxTree.int32_const((value as int_const_node).constant_value); else if (value is long_const_node) return new SyntaxTree.int64_const((value as long_const_node).constant_value); else if (value is sbyte_const_node) return new SyntaxTree.int32_const((value as sbyte_const_node).constant_value); else if (value is short_const_node) return new SyntaxTree.int32_const((value as short_const_node).constant_value); else if (value is uint_const_node) return new SyntaxTree.uint64_const((value as uint_const_node).constant_value); else if (value is ulong_const_node) return new SyntaxTree.uint64_const((value as ulong_const_node).constant_value); else if (value is ushort_const_node) return new SyntaxTree.int32_const((value as ushort_const_node).constant_value); else if (value is string_const_node) return new SyntaxTree.string_const((value as string_const_node).constant_value); else if (value is array_const) { array_const ac = value as array_const; SyntaxTree.expression_list el = new PascalABCCompiler.SyntaxTree.expression_list(); for (int i = 0; i < ac.element_values.Count; ++i) el.Add(ConvertConstant(ac.element_values[i])); SyntaxTree.array_const synAC = new PascalABCCompiler.SyntaxTree.array_const(); synAC.elements = el; return synAC; } else if (value is enum_const_node) { //Есть сомнения, что будет работать во всех случаях enum_const_node ec = value as enum_const_node; SyntaxTree.ident r = new SyntaxTree.ident((ec.type as common_type_node).const_defs[ec.constant_value].name); SyntaxTree.ident l = new SyntaxTree.ident(ec.type.name); return new SyntaxTree.dot_node(l, r); } else if (value is record_constant) { record_constant rc = value as record_constant; SyntaxTree.record_const synRC = new PascalABCCompiler.SyntaxTree.record_const(); for (int i = 0; i < rc.field_values.Count; ++i) { SyntaxTree.record_const_definition rcd = new PascalABCCompiler.SyntaxTree.record_const_definition(); rcd.name = rc.record_const_definition_list[i].name; rcd.val = rc.record_const_definition_list[i].val; synRC.rec_consts.Add(rcd); } return synRC; } else throw new Exception("Не реализовано"); //выяснить, что тут может быть }
/// <summary> /// Возращает диапазоны массива из строки индексеров /// </summary> /// <param name="index_str"></param> /// <returns></returns> private static List<SyntaxTree.diapason> get_diapasons(string index_str) { List<SyntaxTree.diapason> res = new List<PascalABCCompiler.SyntaxTree.diapason>(); string[] diaps = index_str.Split(','); foreach (string str in diaps) { if (str.Trim() == "") { res.Add(null); } else { string left = str.Substring(0, str.IndexOf('.')).Trim(); int from = str.LastIndexOf('.'); string right = str.Substring(from + 1, str.Length - from - 1).Trim(); int val; SyntaxTree.expression left_expr, right_expr; if (Int32.TryParse(left, out val)) { left_expr = new SyntaxTree.int32_const(val); } else left_expr = new SyntaxTree.ident(left); if (Int32.TryParse(right, out val)) { right_expr = new SyntaxTree.int32_const(val); } else right_expr = new SyntaxTree.ident(right); res.Add(new PascalABCCompiler.SyntaxTree.diapason(left_expr, right_expr)); } } return res; }