ДобавленPT4Linq к сандартным модулям

This commit is contained in:
miks1965 2015-08-15 00:31:26 +03:00
parent 5bb5425cfc
commit eb5237b465
13 changed files with 301 additions and 57 deletions

View file

@ -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 = "1008";
public const string Revision = "1010";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%MINOR%=2
%REVISION%=1008
%REVISION%=1010
%MAJOR%=2
%COREVERSION%=0

View file

@ -1,4 +1,4 @@
// Copyright (c) Ivan Bondarev, Stanislav Mihalkovich (for details please see \doc\copyright.txt)
// Copyright (c) Ivan Bondarev, Stanislav Mihalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.IO;
@ -55,7 +55,7 @@ namespace PascalABCCompiler.Errors
fn = Path.GetFileName(FileName);
return string.Format(StringResources.Get("PARSER_ERRORS_COMPILATION_ERROR{0}{1}{2}"), fn, pos, Message);
*/
return (new CompilerInternalError("Errors.ToString",new Exception(string.Format("Íå ïåðåîïåðåäåëåíà {0}.ToString",this.GetType())))).ToString();
return (new CompilerInternalError("Errors.ToString",new Exception(string.Format("Не переопеределена {0}.ToString",this.GetType())))).ToString();
}
public virtual SourceLocation SourceLocation
@ -167,7 +167,7 @@ namespace PascalABCCompiler.Errors
pos = "(?,?)";
else
pos = "(" + source_context.begin_position.line_num + "," + source_context.begin_position.column_num + ")";
return Path.GetFileName(FileName) + pos + ": Ñèíòàêñè÷åñêàÿ îøèáêà : " + Message + snode;
return Path.GetFileName(FileName) + pos + ": Синтаксическая ошибка : " + Message + snode;
}
public override SourceContext SourceContext

View file

@ -1 +1 @@
!define VERSION '2.2.0.1008'
!define VERSION '2.2.0.1010'

View file

@ -4,7 +4,7 @@ uses
DrawManField, Events, FilesOperations, GOLDParserEngine, GraphABC,
GraphABCHelper, IniFile, PointerTools, PointRect, PT4, Robot, RobotField,
RobotTaskMaker, RobotZadan, Sockets, Utils, VCL, Timers, PT4Exam, PT4TaskMakerNET, RBDMUtils,
Collections, Arrays, Core, FormsABC, MPI;
Collections, Arrays, Core, FormsABC, MPI, PT4Linq;
begin
writeln(cos(pi));

View file

@ -91,6 +91,7 @@
File ..\bin\Lib\Utils.pcu
File ..\bin\Lib\VCL.pcu
File ..\bin\Lib\PT4Exam.pcu
File ..\bin\Lib\PT4Linq.pcu
File ..\bin\Lib\PT4TaskMakerNET.pcu
File ..\bin\Lib\RBDMUtils.pcu
File ..\bin\Lib\Collections.pcu
@ -135,6 +136,7 @@
${AddFile} "VCL.pcu"
${AddFile} "PT4TaskMakerNET.pcu"
${AddFile} "PT4Exam.pcu"
${AddFile} "PT4Linq.pcu"
${AddFile} "RBDMUtils.pcu"
${AddFile} "Collections.pcu"
${AddFile} "Core.pcu"
@ -172,6 +174,7 @@
File ..\bin\Lib\PointRect.pas
File ..\bin\Lib\PT4.pas
File ..\bin\Lib\PT4Exam.pas
File ..\bin\Lib\PT4Linq.pas
File ..\bin\Lib\Robot.pas
File ..\bin\Lib\RobotField.pas
File ..\bin\Lib\RobotTaskMaker.pas
@ -216,6 +219,7 @@
${AddFile} "PointRect.pas"
${AddFile} "PT4.pas"
${AddFile} "PT4Exam.pas"
${AddFile} "PT4Linq.pas"
${AddFile} "Robot.pas"
${AddFile} "RobotField.pas"
${AddFile} "RobotTaskMaker.pas"

View file

@ -239,7 +239,7 @@ namespace PascalABCCompiler.SyntaxTree
{
var pal = new procedure_attributes_list(proc_attribute.attr_override);
var fp = new formal_parameters();
var ff = new function_header(fp, pal, "ToString", "string");
var ff = new function_header("ToString", "string", fp, pal);
var cleft = new char_const('(');
var cright = new char_const(')');

View file

@ -86,12 +86,8 @@ namespace PascalABCCompiler.SyntaxTree
//-- List members begin
public List<statement> list
{
get
{
return subnodes;
}
get { return subnodes; }
}
public void AddMany(params statement[] els)
{
list.AddRange(els);
@ -141,6 +137,10 @@ namespace PascalABCCompiler.SyntaxTree
{
list.InsertRange(0, els);
}
public static statement_list Empty
{
get { return new statement_list(); }
}
//-- List members end
}
@ -162,6 +162,14 @@ namespace PascalABCCompiler.SyntaxTree
{ }
public assign(string name, expression ex, SourceContext sc = null) : this(new ident(name), ex, sc)
{ }
public assign(string name, string id) : this(new ident(name), new ident(id))
{ }
public assign(string name, int value) : this(new ident(name), new int32_const(value))
{ }
public assign(string name, double value) : this(new ident(name), new double_const(value))
{ }
public assign(string name, char value) : this(new ident(name), new char_const(value))
{ }
public override string ToString()
{
return string.Format("{0} {1} {2}", to, OperatorServices.ToString(operator_type, LanguageId.PascalABCNET), from);
@ -374,6 +382,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, string type) : this(new ident_list(id), new named_type_reference(type))
{ }
public override string ToString()
{
var sb = new System.Text.StringBuilder();
@ -399,7 +410,6 @@ namespace PascalABCCompiler.SyntaxTree
{
Add(_declaration, sc);
}
public declarations Add(declaration _declaration, SourceContext sc = null)
{
defs.Add(_declaration);
@ -407,33 +417,66 @@ namespace PascalABCCompiler.SyntaxTree
source_context = sc;
return this;
}
public void AddMany(params declaration[] ids)
{
defs.AddRange(ids);
}
public bool Remove(declaration st)
//-- List members begin
public List<declaration> list
{
return defs.Remove(st);
get { return defs; }
}
public void InsertAfter(declaration st, declaration newst)
public void AddMany(params declaration[] els)
{
var ind = defs.FindIndex(x => x == st);
list.AddRange(els);
}
public bool Remove(declaration el)
{
return list.Remove(el);
}
private int FindIndex(declaration el)
{
var ind = list.FindIndex(x => x == el);
if (ind == -1)
throw new Exception(string.Format("У {0} не найден {1} среди дочерних\n", this, st));
defs.Insert(ind + 1, newst);
throw new Exception(string.Format("У списка {0} не найден элемент {1} среди дочерних\n", this, el));
return ind;
}
public void InsertBefore(declaration st, declaration newst)
public void Replace(declaration el, declaration newel)
{
var ind = defs.FindIndex(x => x == st);
if (ind == -1)
throw new Exception(string.Format("У {0} не найден {1} среди дочерних\n", this, st));
defs.Insert(ind, newst);
list[FindIndex(el)] = newel;
}
public void AddFirst(ident st)
public void Replace(declaration el, IEnumerable<declaration> newels)
{
defs.Insert(0, st);
var ind = FindIndex(el);
list.RemoveAt(ind);
list.InsertRange(ind, newels);
}
public void InsertAfter(declaration el, declaration newel)
{
list.Insert(FindIndex(el) + 1, newel);
}
public void InsertBefore(declaration el, declaration newel)
{
list.Insert(FindIndex(el), newel);
}
public void InsertAfter(declaration el, IEnumerable<declaration> newels)
{
list.InsertRange(FindIndex(el) + 1, newels);
}
public void InsertBefore(declaration el, IEnumerable<declaration> newels)
{
list.InsertRange(FindIndex(el), newels);
}
public void AddFirst(declaration el)
{
list.Insert(0, el);
}
public void AddFirst(IEnumerable<declaration> els)
{
list.InsertRange(0, els);
}
public static statement_list Empty
{
get { return new statement_list(); }
}
//-- List members end
}
public partial class program_tree
@ -480,6 +523,10 @@ namespace PascalABCCompiler.SyntaxTree
source_context = sc;
return this;
}
public static expression_list Empty
{
get { return new expression_list(); }
}
public override string ToString()
{
if (expressions.Count == 0)
@ -551,6 +598,13 @@ namespace PascalABCCompiler.SyntaxTree
{ }
public typed_parameters(ident id, type_definition type): this(new ident_list(id), type)
{ }
public override string ToString()
{
var s = this.idents.ToString() + ": " + this.vars_type.ToString();
if (this.inital_value != null)
s += " := " + this.inital_value.ToString();
return s;
}
}
public partial class formal_parameters
@ -566,8 +620,16 @@ namespace PascalABCCompiler.SyntaxTree
source_context = sc;
return this;
}
public override string ToString()
{
return string.Join(",", params_list.Select(p => p.ToString()));
}
public static formal_parameters Empty
{
get { return new formal_parameters(); }
}
}
///
///
public partial class procedure_attributes_list
{
public procedure_attributes_list(procedure_attribute _procedure_attribute, SourceContext sc = null)
@ -607,6 +669,16 @@ namespace PascalABCCompiler.SyntaxTree
}
}
//for sugar
public procedure_header(string name, formal_parameters fp, procedure_attributes_list pal) : this(fp, pal, new method_name(name), null, null)
{ }
public procedure_header(string name, formal_parameters fp) : this(name, fp, new procedure_attributes_list())
{ }
public procedure_header(string name) : this(name, new formal_parameters())
{ }
public override string ToString()
{
var sb = new System.Text.StringBuilder();
@ -632,9 +704,14 @@ namespace PascalABCCompiler.SyntaxTree
}
//for sugar
public function_header(formal_parameters fp, procedure_attributes_list pal, string name, string returntype) : this(fp, pal, new method_name(name), null, new named_type_reference(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)
{ }
public function_header(string name, string returntype, formal_parameters fp) : this(fp, new procedure_attributes_list(), new method_name(name), null, new named_type_reference(returntype), null)
{ }
public function_header(string name, string returntype) : this(new formal_parameters(), new procedure_attributes_list(), new method_name(name), null, new named_type_reference(returntype), null)
{ }
public override string ToString()
{
@ -664,6 +741,49 @@ namespace PascalABCCompiler.SyntaxTree
source_context = null;
is_short_definition = false;
}
public procedure_definition(string name, formal_parameters fp, declarations defs, statement_list code) : this(new procedure_header(name,fp), new block(defs, code))
{ }
public procedure_definition(string name, formal_parameters fp, statement_list code) : this(new procedure_header(name, fp), new block(null, code))
{ }
public procedure_definition(string name, formal_parameters fp, statement st) : this(new procedure_header(name, fp), new block(null, new statement_list(st)))
{ }
public procedure_definition(string name, declarations defs, statement_list code) : this(new procedure_header(name), new block(defs, code))
{ }
public procedure_definition(string name, statement_list code, proc_block b) : this(new procedure_header(name), b)
{ }
public procedure_definition(string name, statement_list code) : this(new procedure_header(name), new block(null, code))
{ }
public procedure_definition(string name, statement st) : this(new procedure_header(name), new block(null, new statement_list(st)))
{ }
public procedure_definition(string name, string rettype, formal_parameters fp, declarations defs, statement_list code) : this(new function_header(name, rettype, fp), new block(defs, code))
{ }
public procedure_definition(string name, string rettype, formal_parameters fp, statement_list code) : this(new function_header(name, rettype, fp), new block(null, code))
{ }
public procedure_definition(string name, string rettype, formal_parameters fp, statement st) : this(new function_header(name, rettype, fp), new block(null, new statement_list(st)))
{ }
public procedure_definition(string name, string rettype, declarations defs, statement_list code) : this(new function_header(name, rettype), new block(defs, code))
{ }
public procedure_definition(string name, string rettype, proc_block b) : this(new function_header(name, rettype), b)
{ }
public procedure_definition(string name, string rettype, statement_list code) : this(new function_header(name, rettype), new block(null, code))
{ }
public procedure_definition(string name, string rettype, statement st) : this(new function_header(name, rettype), new block(null, new statement_list(st)))
{ }
public void AssignAttrList(attribute_list al)
{
if (proc_header != null)
@ -833,13 +953,18 @@ namespace PascalABCCompiler.SyntaxTree
{
access_mod = new access_modifer_node(access);
}
public class_members Add(declaration _declaration, SourceContext sc = null)
public class_members Add(declaration _declaration, SourceContext sc)
{
members.Add(_declaration);
if (sc != null)
source_context = sc;
return this;
}
public void Add(params declaration[] decls)
{
foreach (var d in decls)
members.Add(d);
}
}
public partial class class_body
@ -938,12 +1063,26 @@ namespace PascalABCCompiler.SyntaxTree
{
public constructor(formal_parameters fp, SourceContext sc = null) : this(null, fp, new procedure_attributes_list(), null, false, false, null, null, sc)
{ }
public override string ToString()
{
var sb = new System.Text.StringBuilder();
sb.Append("constructor ");
sb.Append("(" + parameters.ToString() + ")");
sb.Append(";");
return sb.ToString();
}
}
public partial class block
{
public block(statement_list code) : this(null, code, null)
{ }
public static block Empty
{
get { return new block(null, new statement_list()); }
}
}
public partial class case_variants
@ -1101,6 +1240,10 @@ namespace PascalABCCompiler.SyntaxTree
{
public new_expr(type_definition type, expression_list pars, SourceContext sc = null) : this(type, pars, false, null, sc)
{ }
public override string ToString()
{
return "new "+this.type.ToString()+"("+this.params_list.ToString()+")";
}
}
public partial class where_type_specificator_list

View file

@ -7,6 +7,10 @@ using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.ParserTools;
using PascalABCCompiler.Errors;
namespace ParsePABC1
{
class ProcessYieldCapturedVarsVisitor : BaseChangeVisitor
@ -30,11 +34,6 @@ namespace ParsePABC1
//PrintInfo = false;
}
/*public override void visit(procedure_definition pd)
{
} */
public override void Enter(syntax_tree_node st)
{
base.Enter(st);
@ -49,35 +48,62 @@ namespace ParsePABC1
type_declaration GenClassForYield(procedure_definition pd, IEnumerable<var_def_statement> fields)
{
var fh = (pd.proc_header as function_header);
var seqt = fh.return_type as sequence_type;
var stels = seqt.elements_type;
// Теперь на месте процедуры генерируем класс
var cm = new class_members(access_modifer.public_modifer);
foreach (var m in fields)
cm.Add(m);
var st = SyntaxTreeBuilder.BuildSimpleVarDef("state", "integer");
var st = new var_def_statement("state", "integer");
var fh = (pd.proc_header as function_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);
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);
}
var stels = seqt.elements_type;
var cur = new var_def_statement("current", stels);
var pb = pd.proc_body;
var fhh = new function_header(new formal_parameters(),new procedure_attributes_list(),"MoveNext","boolean");
var MoveNext = new procedure_definition(fhh, pb);
var Constr = new procedure_definition(new constructor(formal_parameters.Empty), block.Empty, null);
var MoveNext = new procedure_definition("MoveNext", "boolean", pd.proc_body);
var Reset = new procedure_definition("Reset", statement_list.Empty);
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 GetEnumerator = new procedure_definition("GetEnumerator", "System.Collections.IEnumerator", assG);
pd.proc_body = new block(new statement_list(assG));
cm.Add(st, cur, Constr, Reset, MoveNext, GetCurrent, GetEnumerator);
cm.Add(st).Add(cur).Add(MoveNext);
var interfaces = new named_type_reference_list("System.Collections.IEnumerator","System.Collections.IEnumerable");
var td = new type_declaration(newClassName()+"Helper", SyntaxTreeBuilder.BuildClassDefinition(interfaces, cm));
var td = new type_declaration(className, SyntaxTreeBuilder.BuildClassDefinition(interfaces, cm));
return td;
}
public override void visit(procedure_definition pd)
{
hasYields = false;
mids = new FindMainIdentsVisitor();
if (pd.proc_header is function_header)
mids = new FindMainIdentsVisitor();
base.visit(pd);
if (!hasYields) // т.е. мы разобрали процедуру и уже выходим. Это значит, что пока yield будет обрабатываться только в процедурах. Так это и надо.
if (!hasYields) // т.е. мы разобрали функцию и уже выходим. Это значит, что пока yield будет обрабатываться только в функциях. Так это и надо.
return;
var dld = new DeleteLocalDefs(mids.vars); // mids.vars - все захваченные переменные
@ -89,7 +115,8 @@ namespace ParsePABC1
var cc = GenClassForYield(pd, dld.BlockDeletedIds.Union(dld.LocalDeletedIds));
var cct = new type_declarations(cc);
Replace(pd, cct);
var decls = UpperNodeAs<declarations>();
decls.InsertBefore(pd, cct);
mids = null; // вдруг мы выйдем из процедуры, не зайдем в другую, а там - оператор! Такого конечно не может быть
}
@ -99,6 +126,7 @@ namespace ParsePABC1
hasYields = true;
if (mids != null) // если мы - внутри процедуры
yn.visit(mids);
else throw new SyntaxError("Yield must be in functions only", "", yn.source_context, yn);
// mids.vars - надо установить, какие из них - локальные, какие - из этого класса, какие - являются параметрами функции, а какие - глобальные (все остальные)
// те, которые являются параметрами, надо скопировать в локальные переменные и переименовать использование везде по ходу данной функции
// самое сложное - переменные-поля этого класса - они требуют в создаваемом классе, реализующем итератор, хранить Self текущего класса и добавлять это Self везде по ходу алгоритма

View file

@ -21,11 +21,13 @@ namespace ParsePABC1
var txt = System.IO.File.ReadAllText(fname);
var cu = c.ParsersController.Compile(fname, txt, err, PascalABCCompiler.Parsers.ParseMode.ForFormatter);
var cu = c.ParseText(fname, txt, err);
if (cu == null)
{
WriteLine("Не распарсилось");
if (err.Count > 0)
WriteLine(err[0]);
else WriteLine("Не распарсилось");
}
return cu;
}
@ -34,7 +36,7 @@ namespace ParsePABC1
{
try
{
var cu = ParseFile(@"d:\w5\yield2.pas");
var cu = ParseFile(@"..\..\..\yield2.pas");
if (cu == null)
return;

View file

@ -2,7 +2,7 @@ type A = class
j,k: integer;
end;
function Gen: sequence of integer;
function Gen(a,b: real): sequence of integer;
var j,k: real;
begin
var i := 1;

Binary file not shown.

67
bin/Lib/PT4Linq.pas Normal file
View file

@ -0,0 +1,67 @@
unit PT4Linq;
uses PT4;
function ReadSeqInteger(): IEnumerable<integer>;
begin
result := Range(1, GetInteger()).Select(e -> GetInteger()).ToArray();
end;
function ReadSeqString(): IEnumerable<string>;
begin
result := Range(1, GetInteger()).Select(e -> GetString()).ToArray();
end;
procedure System.Collections.Generic.IEnumerable<T>.Write();
begin
var b := self.ToArray();
PT4.Put(b.Length);
foreach e : T in b do
PT4.Put(e);
end;
function System.Collections.Generic.IEnumerable<TSource>.Show
(cmt: string; selector: System.Func<TSource, string>):
System.Collections.Generic.IEnumerable<TSource>;
begin
var b := self.Select(selector).ToArray();
PT4.Show(cmt);
PT4.Show((b.Length + ':').PadLeft(3));
foreach var e in b do
PT4.Show(e);
PT4.ShowLine();
result := self;
end;
function System.Collections.Generic.IEnumerable<TSource>.Show
(selector: System.Func<TSource, string>):
System.Collections.Generic.IEnumerable<TSource>;
begin
result := self.Show('', selector);
end;
function System.Collections.Generic.IEnumerable<TSource>.Show(cmt: string):
System.Collections.Generic.IEnumerable<TSource>;
begin
result := self.Show(cmt, e -> e.ToString());
end;
function System.Collections.Generic.IEnumerable<TSource>.Show():
System.Collections.Generic.IEnumerable<TSource>;
begin
result := self.Show('');
end;
function ReadAllLines(name: string):
System.Collections.Generic.IEnumerable<string>;
begin
result := System.IO.File.ReadAllLines(name, Encoding.Default);
end;
procedure WriteAllLines(name: string; seq:
System.Collections.Generic.IEnumerable<string>);
begin
System.IO.File.WriteAllLines(name, seq.ToArray, Encoding.Default);
end;
end.