public string CreateTemplateInstance(List <type_node> instance_params, location loc) { class_definition cl_def = _type_decl.type_def as class_definition; template_type_name ttn = _type_decl.type_name as template_type_name; //if (cl_def == null) //{ // throw new PascalSharp.Internal.TreeConverter.CompilerInternalError("No body definition in template class."); //} //if (cl_def.template_args == null || cl_def.template_args.idents == null) //{ // throw new PascalSharp.Internal.TreeConverter.CompilerInternalError("No template arguments in syntax tree."); //} List <ident> template_formals = (_is_synonym) ? ttn.template_args.idents : cl_def.template_args.idents; if (instance_params.Count != template_formals.Count) { throw new PascalSharp.Internal.TreeConverter.SimpleSemanticError(loc, "TEMPLATE_ARGUMENTS_COUNT_MISMATCH"); } return(GetTemplateInstanceName(instance_params)); }
public override void visit(template_type_name node) { text = "Name: " + node.name; }
public virtual void visit(template_type_name _template_type_name) { DefaultVisit(_template_type_name); }
public virtual void post_do_visit(template_type_name _template_type_name) { }
public override void visit(template_type_name _template_type_name) { DefaultVisit(_template_type_name); pre_do_visit(_template_type_name); visit(template_type_name.template_args); post_do_visit(_template_type_name); }
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); }
public virtual void visit(template_type_name _template_type_name) { }
public override void visit(template_type_name _template_type_name) { throw new NotImplementedException(); }
public virtual void visit(template_type_name _template_type_name) { }
public virtual void visit(template_type_name _template_type_name) { DefaultVisit(_template_type_name); }
public override void visit(template_type_name node) { prepare_node(node.template_args, "template_args"); }
public override void visit(template_type_name _template_type_name) { executer.visit(_template_type_name); if (_template_type_name.template_args != null) this.visit((dynamic)_template_type_name.template_args); if (_template_type_name.attributes != null) this.visit((dynamic)_template_type_name.attributes); }