/*void common_diap_check(expression from, expression to) * { * * }*/ void semantic_check_method_call_as_diapason_expr(SyntaxTree.method_call mc) { var from = mc.parameters.expressions[0]; var to = mc.parameters.expressions[1]; var semfrom = convert_strong(from); var b = convertion_data_and_alghoritms.can_convert_type(semfrom, SystemLibrary.SystemLibrary.integer_type); var b1 = false; if (!b) { b1 = convertion_data_and_alghoritms.can_convert_type(semfrom, SystemLibrary.SystemLibrary.char_type); } if (!b && !b1) { AddError(get_location(from), "INTEGER_OR_CHAR_VALUE_EXPECTED"); } var semto = convert_strong(to); var c = convertion_data_and_alghoritms.can_convert_type(semto, SystemLibrary.SystemLibrary.integer_type); var c1 = false; if (!c) { c1 = convertion_data_and_alghoritms.can_convert_type(semto, SystemLibrary.SystemLibrary.char_type); } if (!c && !c1) { AddError(get_location(to), "INTEGER_OR_CHAR_VALUE_EXPECTED"); } if (b != c || c1 != b1) { AddError(get_location(to), "INCOMPATIBLE_DIAPASON_BOUNDS_TYPES"); } }
void semantic_check_method_call_as_slice_expr(SyntaxTree.method_call mc) // нельзя проверять сахарный узел, т.к.могут быть вложенные сахарные expression!! { var v = (mc.dereferencing_value as dot_node).left; var semvar = convert_strong(v); if (semvar is typed_expression) { semvar = convert_typed_expression_to_function_call(semvar as typed_expression); } var IsSlicedType = 0; // проверим, является ли semvar.type динамическим массивом, списком List или строкой if (semvar.type.type_special_kind == SemanticTree.type_special_kind.array_kind) { IsSlicedType = 1; } if (IsSlicedType == 0) { var t = ConvertSemanticTypeNodeToNETType(semvar.type); // не работает для array of T // semvar.type должен быть array of T, List<T> или string if (t == null) { IsSlicedType = 0; // можно ничего не присваивать :) } // else 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(v), "BAD_SLICE_OBJECT"); } var from = mc.parameters.expressions[1]; var to = mc.parameters.expressions[2]; expression step = mc.parameters.expressions.Count > 3 ? mc.parameters.expressions[3] : null; CheckIntegerOrIndex(from); CheckIntegerOrIndex(to); CheckInteger(step); }
private static method_call CreateMethodCall(string methodName, params expression[] exprList) { SyntaxTree.method_call mc = new SyntaxTree.method_call(); mc.dereferencing_value = new ident(methodName); SyntaxTree.expression_list exl = new PascalABCCompiler.SyntaxTree.expression_list(); foreach (expression x in exprList) { exl.Add(x); } mc.parameters = exl; return(mc); }
//private SyntaxTree.uses_list CreateStandartUsesList() //{ // uses_list res = new uses_list(); // unit_or_namespace pabcsystem = new unit_or_namespace(); // pabcsystem.name = new ident_list("PABCSystem"); // res.units.Add(pabcsystem); // return res; //} public procedure_call CreateProcedureCall(string procName, params expression[] exprList) { SyntaxTree.procedure_call pc = new SyntaxTree.procedure_call(); SyntaxTree.method_call mc = new SyntaxTree.method_call(); mc.dereferencing_value = new ident(procName); pc.func_name = mc; SyntaxTree.expression_list exl = new PascalABCCompiler.SyntaxTree.expression_list(); foreach (expression x in exprList) { exl.Add(x); } mc.parameters = exl; return(pc); }
void semantic_check_method_call_as_slice_expr_multi(SyntaxTree.method_call mc) { var v = (mc.dereferencing_value as dot_node).left; var semvar = convert_strong(v); if (semvar is typed_expression) { semvar = convert_typed_expression_to_function_call(semvar as typed_expression); } if (semvar.type.type_special_kind != SemanticTree.type_special_kind.array_kind) { AddError(semvar.location, "SLICES_MULTI_DIMENSIONAL_ARRAY_EXPECTED"); } // Теперь с размерностями разберёмся int rank = 0; if (semvar.type is compiled_type_node) { rank = (semvar.type as compiled_type_node).rank; } else if (semvar.type is common_type_node) { rank = (semvar.type as common_type_node).rank; } if (rank != mc.parameters.Count) { AddError(semvar.location, "NUMBER_OF_SLICES_IN_MULTIDIMENSIONAL_ARRAY_SHOULD_BE_EQUAL_TO_ARRAY_RANK"); } foreach (var param in mc.parameters.expressions) { var p = param as method_call; // Tuple.Create if (p == null) { AddError(semvar.location, "_Compiler_error_param_must_be_Tuple"); } var from = p.parameters.expressions[0]; var to = p.parameters.expressions[1]; var step = p.parameters.expressions[2]; CheckIntegerOrIndex(from); CheckIntegerOrIndex(to); CheckInteger(step); } }
public override void visit(SyntaxTree.procedure_call _procedure_call) { procedure_wait = true; SyntaxTree.method_call mc = null; mc = _procedure_call.func_name as SyntaxTree.method_call; if (mc == null) { SyntaxTree.ident id = _procedure_call.func_name as SyntaxTree.ident; if (id != null) { mc = new SyntaxTree.method_call(); mc.dereferencing_value = id; //DarkStar Add //Добавил т.к. нужно для генерации отладочной инфы mc.source_context = id.source_context; } else { SyntaxTree.addressed_value adrv = _procedure_call.func_name as SyntaxTree.addressed_value; if (adrv != null) { mc = new SyntaxTree.method_call(); mc.dereferencing_value = adrv; //DarkStar Add //Добавил т.к. нужно для генерации отладочной инфы mc.source_context = adrv.source_context; } else { throw new CompilerInternalError("Undefined procedure name"); } } } //statement_node sn=convert_strong(_procedure_call.func_name); statement_node sn = convert_strong(mc); //проверяем на слукчай вызова типа real(a) ... if (/*((sn is base_function_call) && (sn as base_function_call).IsExplicitConversion) || (sn is SemanticTree.IReferenceNode) || (sn is SemanticTree.IGetAddrNode) || (sn is null_const_node) || (sn is simple_array_indexing) || (sn is basic_function_call) || (sn is constant_node) || (sn is class_field_reference)*/ !(sn is base_function_call) && !(sn is exit_procedure) && !(sn is while_break_node) && !(sn is while_continue_node) && !(sn is repeat_break_node) && !(sn is repeat_continue_node) && !(sn is for_break_node) && !(sn is for_continue_node) && !(sn is foreach_break_node) && !(sn is foreach_continue_node) ) AddError(get_location(_procedure_call), "STATEMENT_EXPECTED"); return_value(sn); //_procedure_call.func_name.visit(this); }
public override void visit(matching_expression _matching_expression) { SyntaxTree.procedure_call pc = new SyntaxTree.procedure_call(); SyntaxTree.method_call mc = new SyntaxTree.method_call(); dot_node dot = new dot_node(new ident("PABCSystem"), new ident("KV")); mc.dereferencing_value = dot; pc.func_name = mc; pc.source_context = _matching_expression.source_context; SyntaxTree.expression_list exl = new PascalABCCompiler.SyntaxTree.expression_list(); exl.Add(_matching_expression.left); exl.Add(_matching_expression.right); mc.parameters = exl; visit(pc); }
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 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 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; }
void semantic_check_method_call_as_slice_expr(SyntaxTree.method_call mc) // нельзя проверять сахарный узел, т.к.могут быть вложенные сахарные expression!! { var v = (mc.dereferencing_value as dot_node).left; var from = mc.parameters.expressions[1] as expression; var to = mc.parameters.expressions[2] as expression; expression step = mc.parameters.expressions.Count > 3 ? mc.parameters.expressions[3] : null; var semvar = convert_strong(v); if (semvar is typed_expression) { semvar = convert_typed_expression_to_function_call(semvar as typed_expression); } var IsSlicedType = 0; // проверим, является ли semvar.type динамическим массивом, списком List или строкой if (semvar.type.type_special_kind == SemanticTree.type_special_kind.array_kind) { IsSlicedType = 1; } if (IsSlicedType == 0) { var t = ConvertSemanticTypeNodeToNETType(semvar.type); // не работает для array of T // semvar.type должен быть array of T, List<T> или string if (t == null) { IsSlicedType = 0; // можно ничего не присваивать :) } // else 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(v), "BAD_SLICE_OBJECT"); } var semfrom = convert_strong(from); var b = convertion_data_and_alghoritms.can_convert_type(semfrom, SystemLibrary.SystemLibrary.integer_type); var fromIsIndex = (semfrom is common_constructor_call fromCall) && fromCall.common_type.comprehensive_namespace.namespace_full_name.Equals("PABCSystem") && fromCall.common_type.PrintableName.Equals("SystemIndex"); if (!b && !fromIsIndex) { AddError(get_location(from), "INTEGER_VALUE_EXPECTED"); } // semantic tree - type special kind // staticSystemLib посмотреть. // SystemIndex - переименовать. var semto = convert_strong(to); b = convertion_data_and_alghoritms.can_convert_type(semto, SystemLibrary.SystemLibrary.integer_type); var toIsIndex = (semto is common_constructor_call toCall) && toCall.common_type.comprehensive_namespace.namespace_full_name.Equals("PABCSystem") && toCall.common_type.PrintableName.Equals("SystemIndex"); if (!b && !toIsIndex) { AddError(get_location(to), "INTEGER_VALUE_EXPECTED"); } if (step != null) { var semstep = convert_strong(step); b = convertion_data_and_alghoritms.can_convert_type(semstep, SystemLibrary.SystemLibrary.integer_type); if (!b) { AddError(get_location(step), "INTEGER_VALUE_EXPECTED"); } } }
void semantic_check_method_call_as_inrange_expr(SyntaxTree.method_call mc) { var v = mc.parameters.expressions[0]; var from = mc.parameters.expressions[1]; var to = mc.parameters.expressions[2]; var semv = convert_strong(v); var a = convertion_data_and_alghoritms.can_convert_type(semv, SystemLibrary.SystemLibrary.integer_type); var a1 = false; var ar = false; if (!a) { a1 = convertion_data_and_alghoritms.can_convert_type(semv, SystemLibrary.SystemLibrary.char_type); } if (!a1) { ar = convertion_data_and_alghoritms.can_convert_type(semv, SystemLibrary.SystemLibrary.double_type); } if (!a && !a1 && !ar) { AddError(get_location(v), "INTEGER_OR_REAL_OR_CHAR_VALUE_EXPECTED"); } var semfrom = convert_strong(from); var b = convertion_data_and_alghoritms.can_convert_type(semfrom, SystemLibrary.SystemLibrary.integer_type); var b1 = false; var br = false; if (!b) { b1 = convertion_data_and_alghoritms.can_convert_type(semfrom, SystemLibrary.SystemLibrary.char_type); } if (!b1) { br = convertion_data_and_alghoritms.can_convert_type(semfrom, SystemLibrary.SystemLibrary.double_type); } if (!b && !b1 && !br) { AddError(get_location(from), "INTEGER_OR_REAL_OR_CHAR_VALUE_EXPECTED"); } var semto = convert_strong(to); var c = convertion_data_and_alghoritms.can_convert_type(semto, SystemLibrary.SystemLibrary.integer_type); var c1 = false; var cr = false; if (!c) { c1 = convertion_data_and_alghoritms.can_convert_type(semto, SystemLibrary.SystemLibrary.char_type); } if (!c1) { cr = convertion_data_and_alghoritms.can_convert_type(semto, SystemLibrary.SystemLibrary.double_type); } if (!c && !c1 && !cr) { AddError(get_location(to), "INTEGER_OR_REAL_OR_CHAR_VALUE_EXPECTED"); } var incompbound = true; if (b && c || c1 && b1 || cr && br) { incompbound = false; } if (b && cr || c && br) { incompbound = false; } if (incompbound) { AddError(get_location(to), "INCOMPATIBLE_DIAPASON_BOUNDS_TYPES"); } if (a && b1 || ar && b1 || a1 && b || a1 && c) { AddError(get_location(v), "INCOMPATIBLE_TYPES_OF_ELEMENT_AND_DIAPASON"); } }
//private SyntaxTree.uses_list CreateStandartUsesList() //{ // uses_list res = new uses_list(); // unit_or_namespace pabcsystem = new unit_or_namespace(); // pabcsystem.name = new ident_list("PABCSystem"); // res.units.Add(pabcsystem); // return res; //} public procedure_call CreateProcedureCall(string procName, params expression[] exprList) { SyntaxTree.procedure_call pc = new SyntaxTree.procedure_call(); SyntaxTree.method_call mc = new SyntaxTree.method_call(); mc.dereferencing_value = new ident(procName); pc.func_name = mc; SyntaxTree.expression_list exl = new PascalABCCompiler.SyntaxTree.expression_list(); foreach (expression x in exprList) exl.Add(x); mc.parameters = exl; return pc; }