public override void visit(SyntaxTree.slice_expr sl) { // Новое // Последовательности исключены // Преобразуется в вызов a.SystemSlice(situation,from,to,step) // situation = 0 - ничего не пропущено // situation = 1 - пропущен from // situation = 2 - пропущен to // situation = 3 - пропущены from и to // пропущенность кодируется тем, что в соответствующем поле int.MaxValue var semvar = convert_strong(sl.v); if (semvar is typed_expression) semvar = convert_typed_expression_to_function_call(semvar as typed_expression); var semvartype = semvar.type; // semvartype должен быть array of T, List<T> или string var IsSlicedType = 0; // проверим, является ли semvartype динамическим массивом, списком List или строкой var t = ConvertSemanticTypeNodeToNETType(semvartype); if (t.IsArray) IsSlicedType = 1; else if (t == typeof(System.String)) IsSlicedType = 2; else if (t.IsGenericType && t.GetGenericTypeDefinition()==typeof(System.Collections.Generic.List<>)) IsSlicedType = 3; if (IsSlicedType==0) AddError(get_location(sl.v), "BAD_SLICE_OBJECT"); int situation = 0; if ((sl.from is int32_const) && (sl.from as int32_const).val==int.MaxValue) situation += 1; if ((sl.to is int32_const) && (sl.to as int32_const).val == int.MaxValue) situation += 2; var el = new SyntaxTree.expression_list(); el.Add(new int32_const(situation)); el.Add(sl.from); el.Add(sl.to); if (sl.step != null) el.Add(sl.step); var mc = new method_call(new dot_node(sl.v, new ident("SystemSlice", sl.v.source_context), sl.v.source_context), el, sl.source_context); visit(mc); }
public override void visit(SyntaxTree.function_lambda_call _function_lambda_call) { SyntaxTree.op_type_node _op_type_node = new SyntaxTree.op_type_node(SyntaxTree.Operators.Assignment); for (int i = 0; i < _function_lambda_call.parameters.expressions.Count; i++) { SyntaxTree.assign _assign = new SyntaxTree.assign(_function_lambda_call.f_lambda_def.parameters.expressions[i] as SyntaxTree.addressed_value, _function_lambda_call.parameters.expressions[i] as SyntaxTree.expression, _op_type_node.type); ((SyntaxTree.statement_list)_function_lambda_call.f_lambda_def.proc_body).subnodes.Insert(0, _assign); _assign.source_context = _function_lambda_call.source_context; } SyntaxTree.expression_list el = new SyntaxTree.expression_list(); for (int i = 0; i < _function_lambda_call.f_lambda_def.formal_parameters.params_list.Count; i++) if (i < _function_lambda_call.parameters.expressions.Count) el.expressions.Add(_function_lambda_call.parameters.expressions[i]); else { el.expressions.Add(new SyntaxTree.ident(_function_lambda_call.f_lambda_def.formal_parameters.params_list[i].idents.idents[0].name, _function_lambda_call.source_context)); } SyntaxTree.method_call _method_call = new SyntaxTree.method_call(el); _method_call.source_context = _function_lambda_call.source_context; if (_method_call is SyntaxTree.dereference) { ((SyntaxTree.dereference)_method_call).dereferencing_value = (SyntaxTree.addressed_value)(new SyntaxTree.ident(_function_lambda_call.f_lambda_def.lambda_name, _function_lambda_call.source_context)); } _method_call.visit(this); }
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; }
private SyntaxTree.procedure_call ConvertOperatorToProcedureCall(SyntaxTree.assign _assign) { SyntaxTree.ident operator_name = new PascalABCCompiler.SyntaxTree.ident(name_reflector.get_name(_assign.operator_type)); operator_name.source_context = _assign.to.source_context; SyntaxTree.dot_node dot = new PascalABCCompiler.SyntaxTree.dot_node(_assign.to, operator_name); dot.source_context = _assign.to.source_context; 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); add_methcall.dereferencing_value = dot; 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; }
private void make_attributes_for_declaration(SyntaxTree.unit_module un, common_unit_node cun) { if (cun.attributes != null) { Hashtable ht = new Hashtable(); foreach (SyntaxTree.simple_attribute_list sal in un.attributes.attributes) for (int j = 0; j < sal.attributes.Count; j++) { SyntaxTree.attribute attr = sal.attributes[j]; attribute_converted = true; type_node tn = convert_strong(attr.type); bool is_attr = false; type_node tmp = tn; while (tmp.base_type != null && !is_attr) { is_attr = tmp.base_type == SystemLibrary.SystemLibrary.attribute_type; tmp = tmp.base_type; } if (!is_attr) AddError(get_location(attr), "CLASS_{0}_NOT_ATTRIBUTE", tn.name); bool allowMultiple = false; AttributeTargets targets = get_usage_attrs(tn, out allowMultiple); if (ht.Contains(tn) && !allowMultiple) { AddError(get_location(attr), "DUPLICATE_ATTRIBUTE_{0}_APPLICATION", tn.name); } else ht[tn] = tn; SemanticTree.attribute_qualifier_kind qualifier = SemanticTree.attribute_qualifier_kind.none_kind; if (attr.qualifier != null) if (j == 0) { if (string.Compare(attr.qualifier.name, "return", true) == 0) { if (context.top_function == null) AddError(get_location(attr), "ATTRIBUTE_APPLICABLE_ONLY_TO_METHOD"); if (context.top_function.return_value_type == null || context.top_function.return_value_type == SystemLibrary.SystemLibrary.void_type) AddError(get_location(attr), "EXPECTED_RETURN_VALUE_FOR_ATTRIBUTE"); throw new NotSupportedError(get_location(attr.qualifier)); qualifier = SemanticTree.attribute_qualifier_kind.return_kind; } else throw new NotSupportedError(get_location(attr.qualifier)); } else AddError(get_location(attr.qualifier), "ATTRIBUTE_QUALIFIER_MUST_BE_FIRST"); check_for_usage_attribute(cun, targets, tn.name, get_location(attr), qualifier); attribute_converted = false; SyntaxTree.expression_list cnstr_args = new SyntaxTree.expression_list(); if (attr.arguments != null) { foreach (SyntaxTree.expression e in attr.arguments.expressions) { if (e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident) { break; } else { cnstr_args.expressions.Add(e); } } } expressions_list args = new expressions_list(); for (int i = 0; i < cnstr_args.expressions.Count; i++) { constant_node cn = convert_strong_to_constant_node(cnstr_args.expressions[i]); check_for_strong_constant(cn, get_location(cnstr_args.expressions[i])); args.AddElement(cn); } base_function_call bfc = create_constructor_call(tn, args, get_location(attr)); attribute_node attr_node = new attribute_node(bfc.simple_function_node, tn, get_location(un)); foreach (expression_node en in bfc.parameters) { constant_node cn = convert_strong_to_constant_node(en, en.type); check_for_strong_constant(cn, en.location); attr_node.args.Add(cn); } if (attr.arguments != null) { for (int i = cnstr_args.expressions.Count; i < attr.arguments.expressions.Count; i++) { SyntaxTree.expression e = attr.arguments.expressions[i]; if (!(e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident)) { AddError(get_location(e), "EXPECTED_ATTRIBUTE_INITIALIZER"); } else { SyntaxTree.ident id = (e as SyntaxTree.bin_expr).left as SyntaxTree.ident; SymbolInfo si = tn.find(id.name); definition_node dn = context.check_name_node_type(id.name, si, get_location(id), general_node_type.property_node, general_node_type.variable_node); type_node mem_tn = null; if (dn is property_node) { property_node pn = dn as property_node; attr_node.prop_names.Add(pn); if (pn.set_function == null) AddError(new ThisPropertyCanNotBeWrited(pn, get_location(id))); if (pn.set_function.parameters.Count != 1) AddError(get_location(id), "INDEX_PROPERTY_INITIALIZING_NOT_VALID"); mem_tn = pn.set_function.parameters[0].type; } else if (dn is var_definition_node) { attr_node.field_names.Add(dn as var_definition_node); mem_tn = (dn as var_definition_node).type; } else { throw new CompilerInternalError("Bad general node type for attribute initializer"); } //SyntaxTree.assign tmp_ass = new SyntaxTree.assign(id,(e as SyntaxTree.bin_expr).right,SyntaxTree.Operators.Assignment); //tmp_ass.source_context = e.source_context; //basic_function_call tmp_bfc = convert_strong(tmp_ass) as basic_function_call; constant_node cn = convert_strong_to_constant_node((e as SyntaxTree.bin_expr).right, mem_tn); check_for_strong_constant(cn, get_location((e as SyntaxTree.bin_expr).right)); if (dn is property_node) attr_node.prop_initializers.Add(cn); else attr_node.field_initializers.Add(cn); } } } attr_node.qualifier = qualifier; cun.attributes.AddElement(attr_node); if (cun.namespaces.Count > 0) cun.namespaces[0].attributes.AddElement(attr_node); } } }