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;
}
Exemple #7
0
 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("Не реализовано");         //выяснить, что тут может быть
 }
Exemple #8
0
        /// <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;
        }