private void AutoPropertyDesugaring(simple_property simple_property,
                                            class_members members)
        {
            var id        = NewId("#PField", simple_property.source_context);
            var accessors = new property_accessors();

            accessors.write_accessor  = new write_accessor_name(id, null, null, simple_property.source_context);
            accessors.read_accessor   = new read_accessor_name(id, null, null, simple_property.source_context);
            simple_property.accessors = accessors;

            var def_attribute = definition_attribute.None;

            if (simple_property.attr == definition_attribute.Static)
            {
                def_attribute = definition_attribute.Static;
            }

            List <ident> l = new List <ident>()
            {
                id
            };
            var var_def_statement = new var_def_statement(
                new ident_list(l, simple_property.source_context),
                simple_property.property_type,
                null,
                def_attribute,
                false,
                simple_property.source_context);

            members.Add(var_def_statement);
        }
Exemplo n.º 2
0
        public static class_members BuildOneMemberSection(declaration m)
        {
            var cm = new class_members(access_modifer.public_modifer);

            cm.Add(m);
            return(cm);
        }
Exemplo n.º 3
0
        public static class_members BuildSimpleDeconstructSection(List <ident> fields, List <ident> formal_names, List <type_definition> types)
        {
            var cm = new class_members(access_modifer.public_modifer);

            cm.Add(BuildSimpleDeConstruct(fields, formal_names, types));
            return(cm);
        }
Exemplo n.º 4
0
        public static class_members BuildClassFieldsSection(List <ident> names, List <type_definition> types)
        {
            var cm = new class_members(access_modifer.private_modifer);

            for (int i = 0; i < names.Count; i++)
            {
                cm.Add(new var_def_statement(names[i], types[i]));
            }
            return(cm);
        }
Exemplo n.º 5
0
        public static class_members BuildSimpleReadPropertiesSection(List <ident> names, List <ident> fields, List <type_definition> types)
        {
            var cm = new class_members(access_modifer.public_modifer);

            for (int i = 0; i < names.Count; i++)
            {
                cm.Add(BuildSimpleReadWriteProperty(names[i], fields[i], types[i]));
            }
            return(cm);
        }
        private void ExtendedWriteAccessorDesugaring(write_accessor_name write_accessor,
                                                     simple_property simple_property,
                                                     class_members members)
        {
            var write_accessor_procedure = write_accessor.pr as procedure_definition;

            //extended indexed property
            if (simple_property.parameter_list != null)
            {
                var proc_header_params = new List <ident>();
                var proc_header_types  = new List <type_definition>();

                foreach (var param in simple_property.parameter_list.parameters)
                {
                    foreach (var ident in param.names.idents)
                    {
                        proc_header_params.Add(ident);
                        proc_header_types.Add(param.type);
                    }
                }
                proc_header_params.Add(new ident("value"));
                proc_header_types.Add(simple_property.property_type);

                write_accessor_procedure.proc_header.parameters =
                    SyntaxTreeBuilder.BuildFormalParameters(
                        proc_header_params,
                        proc_header_types);
            }
            else
            {
                write_accessor_procedure.proc_header.parameters.params_list[0].vars_type = simple_property.property_type;
            }

            members.Add(write_accessor_procedure);

            if (simple_property.attr == definition_attribute.Static)
            {
                write_accessor_procedure.proc_header.class_keyword = true;
                var proc_attr = new procedure_attribute(proc_attribute.attr_static);
                proc_attr.source_context = write_accessor_procedure.proc_header.source_context;
                write_accessor_procedure.proc_header.proc_attributes = new procedure_attributes_list(proc_attr);
            }
        }
        private void ExtendedReadAccessorDesugaring(read_accessor_name read_accessor,
                                                    simple_property simple_property,
                                                    class_members members)
        {
            var read_accessor_procedure = read_accessor.pr as procedure_definition;
            var func_header             = (read_accessor_procedure.proc_header as function_header);

            func_header.return_type = simple_property.property_type;

            //extended indexed property
            if (simple_property.parameter_list != null)
            {
                var func_header_params = new List <ident>();
                var func_header_types  = new List <type_definition>();
                foreach (var param in simple_property.parameter_list.parameters)
                {
                    foreach (var ident in param.names.idents)
                    {
                        func_header_params.Add(ident);
                        func_header_types.Add(param.type);
                    }
                }
                func_header.parameters =
                    SyntaxTreeBuilder.BuildFormalParameters(
                        func_header_params,
                        func_header_types);
            }

            members.Add(read_accessor_procedure);

            if (simple_property.attr == definition_attribute.Static)
            {
                read_accessor_procedure.proc_header.class_keyword = true;
                var proc_attr = new procedure_attribute(proc_attribute.attr_static);
                proc_attr.source_context = read_accessor_procedure.proc_header.source_context;
                read_accessor_procedure.proc_header.proc_attributes = new procedure_attributes_list(proc_attr);
            }
        }
        bool VisitTypeclassDeclaration(type_declaration typeclassDeclaration)
        {
            var typeclassDefinition = typeclassDeclaration.type_def as typeclass_definition;

            if (typeclassDefinition == null)
            {
                return(false);
            }

            var typeclassName = typeclassDeclaration.type_name as typeclass_restriction;

            // TODO: typeclassDefinition.additional_restrictions - translate to usual classes

            // Creating interface

            // Get members for typeclass interface
            var interfaceMembers = new List <class_members>();

            foreach (var cm in typeclassDefinition.body.class_def_blocks)
            {
                var cmNew = (class_members)cm.Clone();

                for (int i = 0; i < cmNew.members.Count; i++)
                {
                    var member = cmNew.members[i];
                    if (member is function_header || member is procedure_header)
                    {
                        cmNew.members[i] = member;
                    }
                    else if (member is procedure_definition procDef)
                    {
                        cmNew.members[i] = procDef.proc_header;
                    }
                    AddAttribute(cmNew.members[i], "__TypeclassMemberAttribute");
                    if (cmNew.members[i] is procedure_header ph)
                    {
                        ConvertOperatorNameIdent(ph);
                    }
                }

                interfaceMembers.Add(cmNew);
            }
            var interfaceInheritance = (named_type_reference_list)typeclassDefinition.additional_restrictions?.Clone();

            if (interfaceInheritance != null)
            {
                interfaceInheritance.source_context = null;
                for (int i = 0; i < interfaceInheritance.types.Count; i++)
                {
                    if (interfaceInheritance.types[i] is typeclass_reference tr)
                    {
                        interfaceInheritance.types[i] = TypeclassReferenceToInterfaceName(tr.names[0].name, tr.restriction_args);
                    }
                    else
                    {
                        throw new NotImplementedException("Syntactic Error");
                    }
                }
            }
            var typeclassInterfaceDef =
                SyntaxTreeBuilder.BuildClassDefinition(
                    interfaceInheritance,
                    null, interfaceMembers.ToArray());

            typeclassInterfaceDef.keyword = class_keyword.Interface;
            var typeclassInterfaceName = new template_type_name("I" + typeclassName.name, RestrictionsToIdentList(typeclassName.restriction_args));
            var typeclassInterfaceDecl = new type_declaration(typeclassInterfaceName, typeclassInterfaceDef);

            typeclassInterfaceDecl.attributes = typeclassDeclaration.attributes;
            AddAttribute(
                typeclassInterfaceDecl, "__TypeclassAttribute",
                new expression_list(new string_const(TypeclassRestrictionToString(typeclassName))));


            // Creating class

            var typeclassDefTranslated =
                SyntaxTreeBuilder.BuildClassDefinition(
                    new named_type_reference_list(new template_type_reference(typeclassInterfaceName.name, typeclassName.restriction_args)),
                    null, typeclassDefinition.body.class_def_blocks.ToArray());

            typeclassDefTranslated.attribute = class_attribute.Abstract;
            for (int i = 0; i < typeclassDefTranslated.body.class_def_blocks.Count; i++)
            {
                var cm = typeclassDefTranslated.body.class_def_blocks[i].members;

                for (int j = 0; j < cm.Count; j++)
                {
                    procedure_header header = null;
                    if (cm[j] is procedure_header ph)
                    {
                        header = ph;
                        header.proc_attributes.Add(new procedure_attribute("abstract", proc_attribute.attr_abstract));
                    }
                    else if (cm[j] is procedure_definition pd)
                    {
                        header = pd.proc_header;
                        header.proc_attributes.Add(new procedure_attribute("virtual", proc_attribute.attr_virtual));
                    }

                    ConvertOperatorNameIdent(header);
                }
            }

            /*
             * {
             *  // Add constructor
             *  var cm = typeclassDefTranslated.body.class_def_blocks[0];
             *  var def = new procedure_definition(
             *      new constructor(),
             *      new statement_list(new empty_statement()));
             *  def.proc_body.Parent = def;
             *  def.proc_header.proc_attributes = new procedure_attributes_list();
             *
             *  cm.Add(def);
             * }
             */
            // Add template parameters for typeclass class(derived typeclasses)
            ident_list templates = RestrictionsToIdentList(typeclassName.restriction_args);

            if (typeclassDefinition.additional_restrictions != null)
            {
                for (int i = 0; i < typeclassDefinition.additional_restrictions.types.Count; i++)
                {
                    string name;
                    string templateName;
                    if (typeclassDefinition.additional_restrictions.types[i] is typeclass_reference tr)
                    {
                        name         = tr.names[0].name;
                        templateName = TypeclassRestrctionToTemplateName(name, tr.restriction_args).name;
                    }
                    else
                    {
                        throw new NotImplementedException("SyntaxError");
                    }

                    // Add template parameter
                    templates.Add(templateName);

                    // Add where restriction
                    if (typeclassDefTranslated.where_section == null)
                    {
                        typeclassDefTranslated.where_section = new where_definition_list();
                    }
                    typeclassDefTranslated.where_section.Add(GetWhereRestriction(
                                                                 interfaceInheritance.types[i],
                                                                 templateName));

                    // Add methods from derived typeclasses
                    var body = (instancesAndRestrictedFunctions.typeclasses[name].type_def as typeclass_definition).body;
                    foreach (var cdb in body.class_def_blocks)
                    {
                        var cdbNew = new class_members(cdb.access_mod == null ? access_modifer.none : cdb.access_mod.access_level);
                        foreach (var member in cdb.members)
                        {
                            procedure_header memberHeaderNew;

                            if (member is procedure_header || member is function_header)
                            {
                                memberHeaderNew = (procedure_header)member.Clone();
                                memberHeaderNew.source_context = null;
                            }
                            else if (member is procedure_definition procDefinition)
                            {
                                memberHeaderNew                = (procedure_header)procDefinition.proc_header.Clone();
                                memberHeaderNew.Parent         = null;
                                memberHeaderNew.source_context = null;
                            }
                            else
                            {
                                continue;
                            }

                            var variableName = templateName + "Instance";
                            var parameters   = memberHeaderNew.parameters.params_list.Aggregate(new expression_list(), (x, y) => new expression_list(x.expressions.Concat(y.idents.idents).ToList()));

                            expression methodCall = null;
                            if (memberHeaderNew.name.meth_name is operator_name_ident oni)
                            {
                                ConvertOperatorNameIdent(memberHeaderNew);
                                Debug.Assert(parameters.expressions.Count == 2, "Parameters count for operation should be equal to 2");
                                //methodCall = new bin_expr(parameters.expressions[0], parameters.expressions[1], oni.operator_type);
                            }
                            var callName = new dot_node(variableName, memberHeaderNew.name.meth_name.name);
                            methodCall = new method_call(callName, parameters);
                            statement exec = null;
                            if (memberHeaderNew is function_header)
                            {
                                exec = new assign("Result", methodCall);
                            }
                            else if (memberHeaderNew is procedure_header)
                            {
                                exec = new procedure_call(methodCall as method_call);
                            }
                            var procDef = new procedure_definition(
                                memberHeaderNew,
                                new statement_list(
                                    GetInstanceSingletonVarStatement(templateName),
                                    exec));
                            cdbNew.Add(procDef);
                        }
                        typeclassDefTranslated.body.class_def_blocks.Add(cdbNew);
                    }
                }
            }

            var typeclassNameTanslated = new template_type_name(typeclassName.name, templates, typeclassName.source_context);

            var typeclassDeclTranslated = new type_declaration(typeclassNameTanslated, typeclassDefTranslated, typeclassDeclaration.source_context);

            typeclassDeclTranslated.attributes = typeclassDeclaration.attributes;
            AddAttribute(
                typeclassDeclTranslated, "__TypeclassAttribute",
                new expression_list(new string_const(TypeclassRestrictionToString(typeclassName))));

            Replace(typeclassDeclaration, typeclassDeclTranslated);
            UpperNodeAs <type_declarations>().InsertBefore(typeclassDeclTranslated, typeclassInterfaceDecl);
            visit(typeclassInterfaceDecl);
            visit(typeclassDeclTranslated);

            return(true);
        }