diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 3285fe701..c1bab0648 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "2"; public const string Minor = "2"; public const string Build = "0"; - public const string Revision = "1013"; + public const string Revision = "1014"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index e320d0691..d0f7eae19 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %MINOR%=2 -%REVISION%=1013 +%REVISION%=1014 %MAJOR%=2 %COREVERSION%=0 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 9ed7e8d4c..8cd252f05 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '2.2.0.1013' \ No newline at end of file +!define VERSION '2.2.0.1014' \ No newline at end of file diff --git a/SyntaxTree/tree/TreeHelper.cs b/SyntaxTree/tree/TreeHelper.cs index 6a8067375..0a95668e7 100644 --- a/SyntaxTree/tree/TreeHelper.cs +++ b/SyntaxTree/tree/TreeHelper.cs @@ -257,6 +257,22 @@ namespace PascalABCCompiler.SyntaxTree } } + public partial class template_type_reference + { + public override string ToString() + { + var sb = new System.Text.StringBuilder(); + sb.Append(this.name.ToString()); + sb.Append("<"); + sb.Append(params_list.params_list[0].ToString()); + for (int i = 1; i < params_list.params_list.Count; i++) + sb.Append("," + params_list.params_list[i].ToString()); + sb.Append(">"); + return sb.ToString(); + } + } + + public partial class variable_definitions { public variable_definitions(var_def_statement _var_def_statement, SourceContext sc = null) @@ -386,6 +402,9 @@ namespace PascalABCCompiler.SyntaxTree public var_def_statement(ident id, type_definition type) : this(new ident_list(id), type) { } + public var_def_statement(ident id, type_definition type, expression iv) : this(new ident_list(id), type, iv) + { } + public var_def_statement(ident id, string type) : this(new ident_list(id), new named_type_reference(type)) { } @@ -708,6 +727,12 @@ namespace PascalABCCompiler.SyntaxTree } //for sugar + public function_header(string name, type_definition returntype, formal_parameters fp) : this(fp, new procedure_attributes_list(), new method_name(name), null, returntype, null) + { } + + public function_header(string name, type_definition returntype) : this(new formal_parameters(), new procedure_attributes_list(), new method_name(name), null, returntype, null) + { } + public function_header(string name, string returntype, formal_parameters fp, procedure_attributes_list pal) : this(fp, pal, new method_name(name), null, new named_type_reference(returntype), null) { } @@ -933,7 +958,11 @@ namespace PascalABCCompiler.SyntaxTree { public override string ToString() { - return dereferencing_value.ToString() + "(" + parameters.ToString() + ")"; + string s = dereferencing_value.ToString(); + if (parameters != null) + s += "(" + parameters.ToString() + ")"; + else s += "()"; + return s; } } @@ -1078,14 +1107,16 @@ namespace PascalABCCompiler.SyntaxTree public partial class constructor { - public constructor(formal_parameters fp, SourceContext sc = null) : this(null, fp, new procedure_attributes_list(), null, false, false, null, null, sc) + public constructor(formal_parameters fp, SourceContext sc = null) : this(null, fp, new procedure_attributes_list(), new method_name("Create"), false, false, null, null, sc) { } public override string ToString() { var sb = new System.Text.StringBuilder(); sb.Append("constructor "); - - sb.Append("(" + parameters.ToString() + ")"); + if (parameters != null) + sb.Append("(" + parameters.ToString() + ")"); + else + sb.Append("()"); sb.Append(";"); return sb.ToString(); } @@ -1257,6 +1288,10 @@ namespace PascalABCCompiler.SyntaxTree { public new_expr(type_definition type, expression_list pars, SourceContext sc = null) : this(type, pars, false, null, sc) { } + public new_expr(string type, expression_list pars) : this(new named_type_reference(type), pars, false, null) + { } + public new_expr(string type) : this(new named_type_reference(type), expression_list.Empty, false, null) + { } public override string ToString() { return "new "+this.type.ToString()+"("+this.params_list.ToString()+")"; diff --git a/_ParsePABC1/ParsePABC1/YieldVisitors/ProcessYieldsCapturedVars.cs b/_ParsePABC1/ParsePABC1/YieldVisitors/ProcessYieldsCapturedVars.cs index f6202433f..c566bfb4b 100644 --- a/_ParsePABC1/ParsePABC1/YieldVisitors/ProcessYieldsCapturedVars.cs +++ b/_ParsePABC1/ParsePABC1/YieldVisitors/ProcessYieldsCapturedVars.cs @@ -51,7 +51,7 @@ namespace SyntaxVisitors } } - type_declaration GenClassForYield(procedure_definition pd, IEnumerable fields) + type_declarations GenClassesForYield(procedure_definition pd, IEnumerable fields) { // Теперь на месте процедуры генерируем класс var cm = new class_members(access_modifer.public_modifer); @@ -61,27 +61,30 @@ namespace SyntaxVisitors var st = new var_def_statement("state", "integer"); var fh = (pd.proc_header as function_header); + if (fh == null) + throw new SyntaxError("Only functions can contain yields", "", pd.proc_header.source_context, pd.proc_header); var seqt = fh.return_type as sequence_type; if (seqt == null) throw new SyntaxError("Functions with yields must return sequences", "", fh.return_type.source_context, fh.return_type); List lid = new List(); var pars = fh.parameters; - foreach (var ps in pars.params_list) - { - if (ps.param_kind != parametr_kind.none) - throw new SyntaxError("Parameters of functions with yields must not have 'var', 'const' or 'params' modifier", "", pars.source_context, pars); - if (ps.inital_value != null) - throw new SyntaxError("Parameters of functions with yields must not have initial values", "", pars.source_context, pars); - var_def_statement vds = new var_def_statement(ps.idents, ps.vars_type); - cm.Add(vds); - lid.AddRange(vds.vars.idents); - } + if (pars != null) + foreach (var ps in pars.params_list) + { + if (ps.param_kind != parametr_kind.none) + throw new SyntaxError("Parameters of functions with yields must not have 'var', 'const' or 'params' modifier", "", pars.source_context, pars); + if (ps.inital_value != null) + throw new SyntaxError("Parameters of functions with yields must not have initial values", "", pars.source_context, pars); + var_def_statement vds = new var_def_statement(ps.idents, ps.vars_type); + cm.Add(vds); + lid.AddRange(vds.vars.idents); + } var stels = seqt.elements_type; var cur = new var_def_statement("current", stels); - var Constr = new procedure_definition(new constructor(formal_parameters.Empty), block.Empty, null); + var Constr = new procedure_definition(new constructor(null), block.Empty, null); var MoveNext = new procedure_definition("MoveNext", "boolean", pd.proc_body); @@ -89,85 +92,59 @@ namespace SyntaxVisitors var GetCurrent = new procedure_definition("get_Current", "object", new assign("Result", "current")); - var className = newClassName() + "Helper"; - var assG = new assign("Result", new new_expr(new named_type_reference(className),expression_list.Empty)); + var className = newClassName(); + + var vds1 = new var_statement(new var_def_statement("res", null, new new_expr(className))); + //var assG = new assign("Result", new new_expr(className)); var GetEnumerator = new procedure_definition("GetEnumerator", "System.Collections.IEnumerator", new assign("Result", "Self")); - var stl = new statement_list(assG); + var stl = new statement_list(vds1); foreach (var id in lid) { - var ass = new assign(new dot_node(new ident("Result"), id),id); + var ass = new assign(new dot_node(new ident("res"), id), id); stl.Add(ass); } + stl.Add(new assign("Result", "res")); pd.proc_body = new block(stl); - cm.Add(st, cur, Constr, Reset, MoveNext, GetCurrent, GetEnumerator); - var interfaces = new named_type_reference_list("System.Collections.IEnumerator","System.Collections.IEnumerable"); - var td = new type_declaration(className, SyntaxTreeBuilder.BuildClassDefinition(interfaces, cm)); - return td; - } + var interfaces = new named_type_reference_list("System.Collections.IEnumerator", "System.Collections.IEnumerable"); + var td = new type_declaration(className + "Helper", SyntaxTreeBuilder.BuildClassDefinition(interfaces, cm)); - class ConstructFiniteAutomata - { - public statement_list res = new statement_list(); - statement_list stl; - int curState = 0; + // Второй класс - statement_list curStatList; - statement_list StatListAfterCase = new statement_list(); + var cm1 = new class_members(access_modifer.public_modifer); - case_node cas; // формируемый case + var Constr1 = new procedure_definition(new constructor(null), block.Empty, null); - public ConstructFiniteAutomata(statement_list stl) - { - this.stl = stl; - } + var Dispose1 = new procedure_definition("Dispose", statement_list.Empty); - public void Process(statement st) - { - if (!(st is yield_node || st is labeled_statement)) - { - curStatList.Add(st); - } - if (st is yield_node) - { - var yn = st as yield_node; - curState += 1; - curStatList.Add(new assign("current", yn.ex)); - curStatList.Add(new assign("state", curState)); - curStatList.Add(new assign("Result", new bool_const(true))); - curStatList.Add(new procedure_call(new ident("exit"))); + var assG1 = new assign("Result", new new_expr(new named_type_reference(className), expression_list.Empty)); - curStatList = new statement_list(); - case_variant cv = new case_variant(new expression_list(new int32_const(curState)), curStatList); - cas.conditions.variants.Add(cv); - } - if (st is labeled_statement) - { - var ls = st as labeled_statement; - curStatList = StatListAfterCase; - curStatList.Add(new labeled_statement(ls.label_name,empty_statement.New)); - Process(ls.to_statement); - } - } + var tpl = new template_param_list(stels); + // + var ntr = new named_type_reference("System.Collections.Generic.IEnumerator"); + var ttr2 = new template_type_reference(ntr, tpl); + var fh1 = new function_header("GetEnumerator", ttr2); + var GetEnumerator1 = new procedure_definition(fh1, new block(new statement_list(new assign("Result", "Self")))); - public void Transform() - { - cas = new case_node(new ident("state")); + var GetCurrent1 = new procedure_definition(new function_header("get_Current", stels), new block(new statement_list(new assign("Result", "current")))); - curStatList = new statement_list(); - case_variant cv = new case_variant(new expression_list(new int32_const(curState)), curStatList); - cas.conditions.variants.Add(cv); + cm1.Add(Constr1, GetCurrent1, GetEnumerator1, Dispose1); + //cm1.Add(Constr1, GetEnumerator1, Dispose1); - foreach (var st in stl.subnodes) - Process(st); + var interfaces1 = new named_type_reference_list(className+"Helper"); + var ttr1 = new template_type_reference(new named_type_reference("System.Collections.Generic.IEnumerable"), tpl); - stl.subnodes = SeqStatements(cas,StatListAfterCase).ToList(); - //statement_list res = new statement_list(cas); - res = stl; - } + interfaces1.Add(ttr1).Add(ttr2); + + var td1 = new type_declaration(className, SyntaxTreeBuilder.BuildClassDefinition(interfaces1, cm1)); + + var cct = new type_declarations(td); + cct.Add(td1); + + return cct; } public override void visit(procedure_definition pd) @@ -193,11 +170,9 @@ namespace SyntaxVisitors (pd.proc_body as block).program_code = cfa.res; // Конструируем определение класса - var cc = GenClassForYield(pd, dld.BlockDeletedIds.Union(dld.LocalDeletedIds)); - var cct = new type_declarations(cc); + var cct = GenClassesForYield(pd, dld.BlockDeletedIds.Union(dld.LocalDeletedIds)); - var decls = UpperNodeAs(); - decls.InsertBefore(pd, cct); + UpperNodeAs().InsertBefore(pd, cct); mids = null; // вдруг мы выйдем из процедуры, не зайдем в другую, а там - оператор! Такого конечно не может быть } @@ -215,4 +190,66 @@ namespace SyntaxVisitors //base.visit(yn); } } + + class ConstructFiniteAutomata + { + public statement_list res = new statement_list(); + statement_list stl; + int curState = 0; + + statement_list curStatList; + statement_list StatListAfterCase = new statement_list(); + + case_node cas; // формируемый case + + public ConstructFiniteAutomata(statement_list stl) + { + this.stl = stl; + } + + public void Process(statement st) + { + if (!(st is yield_node || st is labeled_statement)) + { + curStatList.Add(st); + } + if (st is yield_node) + { + var yn = st as yield_node; + curState += 1; + curStatList.Add(new assign("current", yn.ex)); + curStatList.Add(new assign("state", curState)); + curStatList.Add(new assign("Result", new bool_const(true))); + curStatList.Add(new procedure_call(new ident("exit"))); + + curStatList = new statement_list(); + case_variant cv = new case_variant(new expression_list(new int32_const(curState)), curStatList); + cas.conditions.variants.Add(cv); + } + if (st is labeled_statement) + { + var ls = st as labeled_statement; + curStatList = StatListAfterCase; + curStatList.Add(new labeled_statement(ls.label_name, empty_statement.New)); + Process(ls.to_statement); + } + } + + public void Transform() + { + cas = new case_node(new ident("state")); + + curStatList = new statement_list(); + case_variant cv = new case_variant(new expression_list(new int32_const(curState)), curStatList); + cas.conditions.variants.Add(cv); + + foreach (var st in stl.subnodes) + Process(st); + + stl.subnodes = BaseChangeVisitor.SeqStatements(cas, StatListAfterCase).ToList(); + //statement_list res = new statement_list(cas); + res = stl; + } + } + } diff --git a/_ParsePABC1/yield1.pas b/_ParsePABC1/yield1.pas index 067380dc9..18d0c9482 100644 --- a/_ParsePABC1/yield1.pas +++ b/_ParsePABC1/yield1.pas @@ -1,9 +1,11 @@ function Gen: sequence of integer; begin - for var i:=1 to 10 do - yield i*i; + yield 1; + yield 5; end; begin - + var q := Gen(); + foreach var x in q do + Print(x); end. \ No newline at end of file diff --git a/_ParsePABC1/yield2.pas b/_ParsePABC1/yield2.pas index a764d7ef6..43a1ee267 100644 --- a/_ParsePABC1/yield2.pas +++ b/_ParsePABC1/yield2.pas @@ -1,8 +1,4 @@ -type A = class - j,k: integer; -end; - -function Gen(a,b: real): sequence of integer; +function Gen(a,b: integer): sequence of integer; var j,k: real; begin var i := 1; @@ -15,4 +11,6 @@ begin end; begin + foreach var x in Gen(1,2) do + Print(x); end. \ No newline at end of file diff --git a/bin/Lib/PABCRtl.dll b/bin/Lib/PABCRtl.dll index 39abd93f3..29495e99f 100644 Binary files a/bin/Lib/PABCRtl.dll and b/bin/Lib/PABCRtl.dll differ