diff --git a/ReleaseGenerators/PT4/PT4pabc.dll b/ReleaseGenerators/PT4/PT4pabc.dll index 7e7cd3acc..08631869e 100644 Binary files a/ReleaseGenerators/PT4/PT4pabc.dll and b/ReleaseGenerators/PT4/PT4pabc.dll differ diff --git a/SyntaxTreeConverters/StandardSyntaxConverter.cs b/SyntaxTreeConverters/StandardSyntaxConverter.cs index 5ef8fc1e1..5f9c061d5 100644 --- a/SyntaxTreeConverters/StandardSyntaxConverter.cs +++ b/SyntaxTreeConverters/StandardSyntaxConverter.cs @@ -87,7 +87,7 @@ namespace PascalABCCompiler.SyntaxTreeConverters CacheFunctionVisitor.New.ProcessNode(root); // При наличии файла lightpt.dat подключает модули LightPT и Tasks - root = TeacherContolConverter.New.Convert(root); + root = TeacherControlConverter.New.Convert(root); #if DEBUG //new SimplePrettyPrinterVisitor("D:\\Tree.txt").ProcessNode(root); diff --git a/SyntaxVisitors/TeacherControl/TeacherControl.cs b/SyntaxVisitors/TeacherControl/TeacherControl.cs index d6483c0c9..205ef8350 100644 --- a/SyntaxVisitors/TeacherControl/TeacherControl.cs +++ b/SyntaxVisitors/TeacherControl/TeacherControl.cs @@ -8,11 +8,11 @@ using PascalABCCompiler.SyntaxTree; namespace SyntaxVisitors { - public class TeacherContolConverter : WalkingVisitorNew + public class TeacherControlConverter : WalkingVisitorNew { - public static TeacherContolConverter New + public static TeacherControlConverter New { - get { return new TeacherContolConverter(); } + get { return new TeacherControlConverter(); } } public string Name { get => "TeacherContolConverter"; } @@ -33,12 +33,16 @@ namespace SyntaxVisitors if (program.used_units == null) program.used_units = new uses_list(); + // Добавляем в начало, а секции инициализации вызываются последними + // Проверять, какой CurrentIOSystem подключен, и если не стандартный, то не подключать Light + // Пробуем добавить последними, тогда секции инициализации LightPT вызываются первыми, + // что переключает ввод на LightPT, + // а секции финализации - последними (хорошо) program.used_units.Add(new unit_or_namespace("LightPT", null)); program.used_units.Add(new unit_or_namespace("Tasks", null)); } catch - { - + { } return root; } diff --git a/bin/Lib/LightPT.pas b/bin/Lib/LightPT.pas index 969e4eddf..65ff8bf14 100644 --- a/bin/Lib/LightPT.pas +++ b/bin/Lib/LightPT.pas @@ -25,7 +25,7 @@ var TaskException: PTException := new PTException; WriteInfoCallBack: procedure (name: string; result: TaskStatus; AdditionalInfo: string); - + type InputCountException = class(PTException) // Ровно Count Count: integer; // Count - сколько введено @@ -108,6 +108,8 @@ var function TaskName := ExtractFileName(System.Environment.GetCommandLineArgs[0]).Replace('.exe', ''); +function IsPT := TypeName(CurrentIOSystem) = 'IOPT4System'; + function cInt := typeof(integer); function cRe := typeof(real); function cStr := typeof(string); @@ -264,24 +266,28 @@ function ReArr(n: integer): array of real := (1..n).Select(x -> Re).ToArray; function Random(a, b: integer): integer; begin Result := PABCSystem.Random(a, b); + if IsPT then exit; InputList.Add(Result); end; function Random: real; begin Result := PABCSystem.Random; + if IsPT then exit; InputList.Add(Result); end; function Random(a, b: real): real; begin Result := PABCSystem.Random(a, b); + if IsPT then exit; InputList.Add(Result); end; function Random2(a, b: integer): (integer, integer); begin Result := PABCSystem.Random2(a, b); + if IsPT then exit; InputList.Add(Result[0]); InputList.Add(Result[1]); end; @@ -289,6 +295,7 @@ end; function Random2(a, b: real): (real, real); begin Result := PABCSystem.Random2(a, b); + if IsPT then exit; InputList.Add(Result[0]); InputList.Add(Result[1]); end; @@ -296,6 +303,7 @@ end; function ReadString: string; begin Result := PABCSystem.ReadString; + if IsPT then exit; InputList.Add(Result); NewLineBeforeMessage := True; end; @@ -309,6 +317,7 @@ function ReadlnString2 := ReadString2; function ReadInteger(prompt: string): integer; begin Result := PABCSystem.ReadInteger(prompt); + if IsPT then exit; OutputList.RemoveAt(OutputList.Count - 1); OutputList.RemoveAt(OutputList.Count - 1); NewLineBeforeMessage := True; @@ -317,6 +326,7 @@ end; function ReadInteger2(prompt: string): (integer, integer); begin Result := PABCSystem.ReadInteger2(prompt); + if IsPT then exit; OutputList.RemoveAt(OutputList.Count - 1); OutputList.RemoveAt(OutputList.Count - 1); NewLineBeforeMessage := True; @@ -328,7 +338,8 @@ begin foreach var ob in args do begin PABCSystem.Print(ob); - OutputList.RemoveAt(OutputList.Count - 1) + if not IsPT then + OutputList.RemoveAt(OutputList.Count - 1) end; NewLineBeforeMessage := False; end; @@ -337,12 +348,14 @@ procedure Println(params args: array of object); begin Print(args); Writeln; + if IsPT then exit; NewLineBeforeMessage := True; end; procedure Print(ob: object); begin PABCSystem.Print(ob); + if IsPT then exit; OutputList.RemoveAt(OutputList.Count - 1); NewLineBeforeMessage := False; end; @@ -350,6 +363,7 @@ end; procedure Print(s: string); begin PABCSystem.Print(s); + if IsPT then exit; OutputList.RemoveAt(OutputList.Count - 1); NewLineBeforeMessage := False; end; @@ -378,7 +392,7 @@ type NewLineBeforeMessage := True; end; - procedure readln; virtual; + procedure readln; override; begin inherited readln; NewLineBeforeMessage := True; @@ -585,8 +599,8 @@ end; procedure ColoredMessage(msg: string; color: MessageColorT := MsgColorRed); begin if not NewLineBeforeMessage then - Writeln; - Writeln(MsgColorCode(color) + msg); + Console.WriteLine; + Console.WriteLine(MsgColorCode(color) + msg); end; function NValues(n: integer): string; @@ -660,9 +674,15 @@ begin end; initialization - CurrentIOSystem := new IOLightSystem; + // Если LightPT добавляется в конец uses, то ее секция инициализации вызывается первой + // В этом случае ввод-вывод обязательно переключается, но потом он перекрывается и в основной программе не срабатывает + // Но в CheckPT используется ColoredMessage, которая выводит с помощью Console.WriteLine - ей всё равно + var tn := TypeName(CurrentIOSystem); + if (tn = 'IOStandardSystem') or (tn = '__ReadSignalOISystem') or (tn = 'IOGraphABCSystem') then + CurrentIOSystem := new IOLightSystem; + {if tn = 'IOPT4System' then + IsPT := True;} WriteInfoCallBack := WriteInfoToLocalDatabase; finalization - CurrentIOSystem := new IOLightSystem; // Для Robot - т.к. он переопределяет. Лучше вставлять uses LightPT после Робота CheckMyPT end. \ No newline at end of file diff --git a/bin/Lib/PT4.pas b/bin/Lib/PT4.pas index 614ba8661..752d5d124 100644 --- a/bin/Lib/PT4.pas +++ b/bin/Lib/PT4.pas @@ -802,6 +802,7 @@ procedure PrintMatr(a: List>); // == Конец дополнений к версии 4.14 == +function GetSolutionInfo: string; implementation @@ -847,6 +848,7 @@ procedure _GetP(var param: IntPtr); external '%PABCSYSTEM%\PT4\PT4PABC.dll' procedure _PutP(param: IntPtr); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'putp'; procedure DisposeP(sNode: IntPtr); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'disposep'; function FinishPT(): integer; external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'finishpt'; // == 4.13 == +procedure _GetSolutionInfo(info: System.Text.StringBuilder);external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'getsolutioninfo'; procedure Dispose(p: pointer); begin @@ -3096,8 +3098,16 @@ end; // == Конец дополнений к версии 4.14 == +function GetSolutionInfo: string; +begin + var val := new System.Text.StringBuilder(500); + _getsolutioninfo(val); + result := val.ToString; +end; + initialization __InitModule; finalization __FinalizeModule__; + GetSolutionInfo; end. \ No newline at end of file diff --git a/bin/Lib/XLSX.pas b/bin/Lib/XLSX.pas index ed0a0c403..a89a5f992 100644 --- a/bin/Lib/XLSX.pas +++ b/bin/Lib/XLSX.pas @@ -25,8 +25,17 @@ begin Result := DateTime.Parse(Self); end; -function ToCR(Self: string); extensionmethod -:= (self[2:].ToI - 1, self[1] - 'A'); // 'B3' -> [1,2] +function ToCR(Self: string):(integer,integer); extensionmethod; // 'AA7' -> (6,26) +begin + var clm := 0; + var row := 0; + foreach var c in Self do + if c in 'A'..'Z' then + clm := clm*26 + (c - 'A'+1) + else + row := row*10 + (c - '0'); + Result := (row-1,clm-1); +end; function Load(path: string): XmlElement; begin @@ -64,30 +73,34 @@ begin var (w, h) := (RD[1] - LU[1] + 1, RD[0] - LU[0] + 1); var sheet: array of array of string; - setLength(sheet, h); - for var i := 0 to h - 1 do sheet[i] := new string[w]; - - foreach var node: XmlNode in elms.Item['sheetData'].ChildNodes do - begin - foreach var cell: XmlNode in node.ChildNodes do + if (w<0)or(h<0) then + setLength(sheet,0) + else begin + setLength(sheet, h); + for var i := 0 to h - 1 do sheet[i] := new string[w]; + + foreach var node: XmlNode in elms.Item['sheetData'].ChildNodes do begin - var (i, j) := cell.Attributes.GetNamedItem('r').Value.ToCR; - i -= LU[0]; - j -= LU[1]; - var typ := cell.Attributes.GetNamedItem('t'); - var st := cell.Attributes.GetNamedItem('s'); - var shared := false; - if (typ <> nil) and (typ.Value = 's') then - shared := true; - var value := ''; - foreach var vl: XmlNode in cell.ChildNodes do - if vl.Name = 'v' then value := vl.InnerText; - if shared then - sheet[i, j] := shStr[value.ToInteger] - else if (st <> nil) and (numFmt[st.Value.ToI] in DateTypeId) then - sheet[i, j] := (new DateTime(1900, 1, 1)).AddDays(value.ToI - 2).ToString('dd.MM.yyyy') - else - sheet[i, j] := value; + foreach var cell: XmlNode in node.ChildNodes do + begin + var (i, j) := cell.Attributes.GetNamedItem('r').Value.ToCR; + i -= LU[0]; + j -= LU[1]; + var typ := cell.Attributes.GetNamedItem('t'); + var st := cell.Attributes.GetNamedItem('s'); + var shared := false; + if (typ <> nil) and (typ.Value = 's') then + shared := true; + var value := ''; + foreach var vl: XmlNode in cell.ChildNodes do + if vl.Name = 'v' then value := vl.InnerText; + if shared then + sheet[i, j] := shStr[value.ToInteger] + else if (st <> nil) and (numFmt[st.Value.ToI] in DateTypeId) then + sheet[i, j] := (new DateTime(1900, 1, 1)).AddDays(value.ToI - 2).ToString('dd.MM.yyyy') + else + sheet[i, j] := value; + end; end; end; Result := sheet; diff --git a/bin/PT4/pt4pabc.dll b/bin/PT4/pt4pabc.dll index 7e7cd3acc..08631869e 100644 Binary files a/bin/PT4/pt4pabc.dll and b/bin/PT4/pt4pabc.dll differ