//инициализация критических секций с созданием класса private static void InitCriticals(syntax_tree_visitor visitor) { //генерируем класс SyntaxTree.type_declarations TypeDecls = new PascalABCCompiler.SyntaxTree.type_declarations(); SyntaxTree.type_declaration TypeDecl = new PascalABCCompiler.SyntaxTree.type_declaration(); TypeDecls.types_decl.Add(TypeDecl); LocksName = visitor.context.get_free_name("$locks_container{0}"); TypeDecl.type_name = new PascalABCCompiler.SyntaxTree.ident(LocksName); SyntaxTree.class_definition ClassDef = new PascalABCCompiler.SyntaxTree.class_definition(); TypeDecl.type_def = ClassDef; SyntaxTree.class_body ClassBody = new PascalABCCompiler.SyntaxTree.class_body(); ClassDef.body = ClassBody; SyntaxTree.class_members ClassMember = new PascalABCCompiler.SyntaxTree.class_members(); ClassBody.class_def_blocks.Add(ClassMember); ClassMember.access_mod = new PascalABCCompiler.SyntaxTree.access_modifer_node(PascalABCCompiler.SyntaxTree.access_modifer.public_modifer); List<string> ProcessedNames = new List<string>(); foreach (KeyValuePair<SyntaxTree.compiler_directive, DirectiveInfo> pair in DirInfosTable) { if (pair.Value.Kind == DirectiveKind.Critical) { string LockName = "$default"; if (pair.Value.Name.Length != 0) LockName = pair.Value.Name; if (ProcessedNames.Contains(LockName)) continue; ProcessedNames.Add(LockName); SyntaxTree.var_def_statement vds = new PascalABCCompiler.SyntaxTree.var_def_statement(); SyntaxTree.ident_list idl = new PascalABCCompiler.SyntaxTree.ident_list(); vds.vars = idl; idl.Add(new SyntaxTree.ident(LockName)); SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference(); vds.vars_type = ntr; ntr.Add(new SyntaxTree.ident("object")); SyntaxTree.new_expr ne = new PascalABCCompiler.SyntaxTree.new_expr(); vds.inital_value = ne; ne.type = ntr; vds.var_attr = PascalABCCompiler.SyntaxTree.definition_attribute.Static; ClassMember.members.Add(vds); } } //сохраняем контекст ContextInfo contextInfo = new ContextInfo(visitor); try { visitor.visit(TypeDecls); LocksInitialized = true; } finally { //восстанавливаем контекст contextInfo.RestoreContext(visitor); } }
private static SyntaxTree.type_declarations CreateClass(string ClassName,out SyntaxTree.class_members ClassMember, VarInfoContainer Vars) { //генерация класса SyntaxTree.type_declarations TypeDecls = new PascalABCCompiler.SyntaxTree.type_declarations(); SyntaxTree.type_declaration TypeDecl = new PascalABCCompiler.SyntaxTree.type_declaration(); TypeDecls.types_decl.Add(TypeDecl); TypeDecl.type_name = new PascalABCCompiler.SyntaxTree.ident(ClassName); SyntaxTree.class_definition ClassDef = new PascalABCCompiler.SyntaxTree.class_definition(); TypeDecl.type_def = ClassDef; SyntaxTree.class_body ClassBody = new PascalABCCompiler.SyntaxTree.class_body(); ClassDef.body = ClassBody; ClassMember = new PascalABCCompiler.SyntaxTree.class_members(); ClassBody.class_def_blocks.Add(ClassMember); ClassMember.access_mod = new PascalABCCompiler.SyntaxTree.access_modifer_node(PascalABCCompiler.SyntaxTree.access_modifer.public_modifer); // генерация полей класса // shared переменные for (int i = 0; i < Vars.SharedVariables.Count; ++i) ClassMember.members.Add(CreateClassMember(Vars.SharedVariables[i], "")); // переменные редукции - с долларовым префиксом for (int i = 0; i < Vars.ReductionVariables.Count; ++i) ClassMember.members.Add(CreateClassMember(Vars.ReductionVariables[i], "$")); return TypeDecls; }