Ошибки PascalABC.NET

Интеллисенс ввел вас в заблуждение. Надо исправить

Что делать - пока это один из наиболее доступных “компасов” в океане новых возможностей языка.

1 лайк

Не работает кортежное присваивание вот в таком примере (пытался упростить, но на скорую руку не сильно упростилось).

type SNode<T> = class
    data: T;
    next: SNode<T>;
end;

var mynil : SNode<integer> = nil;

function g := (mynil, mynil);

begin
    var f, l : SNode<integer>;
    (f, l) := g();
end.

Исправили

1 лайк

Может, это не считается ошибкой, но вот такая проблема. Нижеследующая программа в последних версиях (конец 2015 — начало 2016) выводила 1, а сейчас выводит [1,2,3]. Из-за этого поломалось несколько старых программ :frowning:

procedure g<T>(params a:array of T);
begin
  write(a[0]);
end;

procedure f<T>(params a:array of T);
begin
  g(a);
end;

begin
  f(1,2,3);
end.

Кажется мне, что Intellisense как-то неправильно показывает подсказки для кортежей.

type
  DNode<T> = class
  public 
    
    /// Поле данных
    data: T;
    
    /// Поле связи с предыдущим узлом
    prev: DNode<T>;
    
    /// Поле связи со следующим узлом
    next: DNode<T>;
    
    /// <summary>
    /// Инициализирует новый экземпляр узла двусвязного списка
    /// со значением dt поля данных и ссылками prev, next на соседние узлы
    /// </summary>
    /// <param name="dt">Значение поля данных узла</param>
    /// <param name="prev">Сслыка на предыдущий узел</param>
    /// <param name="next">Сслыка на следующий узел</param>
    constructor(dt: T; prev, next: DNode<T>);
    begin
      data := dt;
      self.prev := prev;
      self.next := next;
    end;
  end;

/// Тип для облегчения работы с двусвязными списками
type
  DList<T> = (DNode<T>, DNode<T>);

/// Создание узла двусвязного списка
function MkDNode<T>(dt: T; prev: DNode<T> := nil; next: DNode<T> := nil):= new DNode<T>(dt, prev, next);

/// Создание двусвязного списка по массиву заданных элементов
function CreateDList<T>(params a: array of T): DList<T>;
begin
  var firstD: DNode<T> := nil;
  if (a = nil) or (a.Length = 0) then
  begin
    Result := Rec(firstD, firstD);
    exit;
  end;
  
  firstD := MkDNode(a[0]);
  var lastD := firstD;
  
  for var i := 1 to a.Length - 1 do
  begin
    lastD := MkDNode(a[i], lastD);
    lastD.prev.next := lastD;
  end;
  
  Result := Rec(firstD, lastD);
  
end;

begin
  var five := CreateDList(1, 2, 3, 4, 5);
  Write(five.Item3.data);
end.

Из данного кода видно, что функция CreateDList возвращает кортеж, где Item1 - ссылка на первый элемент списка, а Item2 - ссылка на последний элемент. Однако по точке нам показывается целых 5 Item’ов. Если создать список из 6 элементов, то по точке соответственно будет показываться уже 6 Item’ов. Естественно, все Item’ы дальше второго работать не будут.

Исправлено

Минутка загадочного

unit test;

interface

/// Создаёт текстовый файл на основе заданного текстового. 
/// Новый файл состоит из тех строк, которые начинаются с заданного символа
procedure LinesStartsWith(fname, new_fname: string; c: char);

implementation

procedure LinesStartsWith(fname, new_fname: string; c: char);
begin
  Assert(fname <> '', 'File name cannot be empty');
  Assert(new_fname <> '', 'Name of a new file cannot be empty');
  
  WriteAllLines(new_fname, ReadLines(fname).ToArray.FindAll(x -> x.StartsWith(c)));
  
end;

end.

Загадочное заключается в том, что FindAll почему-то не показывается по точке. А если написать модуль в сокращённой форме, то показывается. Ну и если в основной программе строить такую конструкцию, то всё показывается.

Не показываются впрочем все 5 Find’ов, от Except до First.

Тут нет.

А тут есть.

В ходе небольшого расследования выяснилось, что в подсказке по точке пропадает ещё много чего (Slice, Sort, Sorted и т.д.). Кажется, что пропадает всё добавленное вручную в Паскаль, а пришедшее из .NET остаётся.

1 лайк

Работая с модулем GraphABC при работе с рисунками (picture) возникает такая ошибка, что изменяя рисунок и присваивая его значения другому и изменив первый снова, второй и первый рисунок становятся идентичными. К примеру вот такой код

    Uses GraphAbc;
Var p, a,b,c:picture;
Begin
 p:=picture.Create(100,100);
 a:=picture.Create(100,100);
 b:=picture.Create(100,100);
 c:=picture.Create(100,100);
 a:=p;
 p.Circle(40,40,20);
 b:=p;
 p.Rectangle(40,40,60,60);
 c:=p;
 p.Draw(0,0);
 a.Draw(0,150);
 b.Draw(150,0);
 c.Draw(150,150);
end.

Казалось бы a<>b<>c<>p. Однако при выводе рисунков на экран получается 4 идентичные картинки. Скажите, это также не должно работать как и p.floodfill ? Или можно каким-то образом изменить код.

p. s. Один маленький вопрос. Есть ли какой-либо модуль, или команда (класс, объект) который бы мог выводить звук?

System.Console.Beep({частота}, {длительность_в_миллисекундах}); — через системный спикер (если таковой имеется ;–)

А проигрывание файла так:

    {$reference 'PresentationCore.dll'}
uses
  GraphABC;
    begin
      var fsound := new System.Windows.Media.MediaPlayer;
          fsound.Open(new System.Uri('Новый год в салоне самолета.mp3', System.UriKind.Relative));
          fsound.Play;
    end.
1 лайк

У Вас в коде a,b,c,p ссылаются на одну картинку. Поэтому всё работает так как и полагается. То есть, у Вас a=b=c=p.

Пишите

a.Circle(40,40,20);
b.Rectangle(40,40,60,60);

Посмотрите также в справке раздел Ссылочные типы

да, а можно ли как-то сделать осциллятор звука

Наверно, здесь это есть https://github.com/filoe/cscore

//Находит все слова исходного файла, которые встречаются в words.txt и записывает их в новый файл
procedure FindAndWrite(fname, fname1: string);
begin
  assert((fname <> ''), 'Incorrect fname!');
  assert((fname1 <> ''), 'Incorrect fname1!');
  var f1, f2, f3: text;
  try
    assign(f1, 'words.txt');
    assign(f2, fname);
    assign(f3, fname1);
    try
      reset(f1);
      reset(f2);
      rewrite(f3);
      var words := ReadLines('words.txt');
      while not SeekEof(f2) do
      begin
        var flag := false;
        var x: string;
        readln(f2, x);
        foreach var p: string in words do    
          if not Flag and (x.IndexOf(p) = 0) and (x.Length = p.Length) then
          begin
            writeln(f3, x);
            flag := true;
          end;
      end;
      writeln('Файл создан.');
    finally
      f1.Close;
      f2.Close;
      f3.Close;
    end;
  except
    writeln('Ошибка в FindAndWrite!');
  end;
end;

На ноутбуке всё работает нормально (стоит версия 3.1. сборка 1172) На компьютере же выскакивает такая ошибка (стоит версия 3.1, сборка 1215): () :

Внутренняя ошибка компилятора в модуле [pabcnetc.exe] :'System.Exception: System.IO.EndOfStreamException: Чтение после конца потока невозможно.
   в System.IO.BinaryReader.ReadByte()
   в PascalABCCompiler.PCU.PCUReader.GetTypeReference()
   в PascalABCCompiler.PCU.PCUReader.CreateInterfaceCommonType(String name, Int32 offset)
   в PascalABCCompiler.PCU.PCUReader.GetCommonType(Int32 offset)
   в PascalABCCompiler.PCU.PCUReader.GetTypeReference(Int32 offset)
   в PascalABCCompiler.PCU.PCUReader.ReadCommonExtType()
   в PascalABCCompiler.PCU.PCUReader.GetTypeReference()
   в PascalABCCompiler.PCU.PCUReader.CreateLocalBlockVariable(statements_list stmt)
   в PascalABCCompiler.PCU.PCUReader.CreateStatementList()
   в PascalABCCompiler.PCU.PCUReader.CreateStatement()
   в PascalABCCompiler.PCU.PCUReader.GetCode(Int32 offset)
   в PascalABCCompiler.PCU.wrapped_function_body.restore()
   в PascalABCCompiler.TreeRealization.common_namespace_function_call..ctor(common_namespace_function_node namespace_func, location loc)
   в PascalABCCompiler.TreeConverter.convertion_data_and_alghoritms.create_common_namespace_function_call(common_namespace_function_node cnfn, ILocation loc, expression_node[] exprs)
   в PascalABCCompiler.TreeConverter.convertion_data_and_alghoritms.create_simple_function_call(function_node fn, location loc, expression_node[] exprs)
   в PascalABCCompiler.TreeConverter.convertion_data_and_alghoritms.create_full_function_call(expressions_list exprs, SymbolInfo si, location loc, common_type_node converted_type, common_function_node top_function, Boolean allow_procedure)
   в PascalABCCompiler.TreeConverter.syntax_tree_visitor.visit_method_call(method_call _method_call)
   в PascalABCCompiler.TreeConverter.syntax_tree_visitor.visit(method_call _method_call)
   в PascalABCCompiler.SyntaxTree.method_call.visit(IVisitor visitor)
   в PascalABCCompiler.TreeConverter.returner.visit(expression expr)
   в PascalABCCompiler.TreeConverter.syntax_tree_visitor.convert_strong(expression expr)
   в PascalABCCompiler.TreeConverter.syntax_tree_visitor.visit(procedure_call _procedure_call)
   в PascalABCCompiler.SyntaxTree.procedure_call.visit(IVisitor visitor)
   в PascalABCCompiler.TreeConverter.syntax_tree_visitor.convert_strong(statement st)
   в PascalABCCompiler.TreeConverter.syntax_tree_visitor.visit(statement_list _statement_list)
   в PascalABCCompiler.SyntaxTree.statement_list.visit(IVisitor visitor)
   в PascalABCCompiler.TreeConverter.syntax_tree_visitor.convert_strong(statement st)
   в PascalABCCompiler.TreeConverter.syntax_tree_visitor.visit_program_code(statement_list program_code)
   в PascalABCCompiler.TreeConverter.syntax_tree_visitor.visit(block _block)
   в PascalABCCompiler.SyntaxTree.block.visit(IVisitor visitor)
   в PascalABCCompiler.TreeConverter.syntax_tree_visitor.hard_node_test_and_visit(syntax_tree_node tn)
   в PascalABCCompiler.TreeConverter.syntax_tree_visitor.visit(program_module _program_module)
   в PascalABCCompiler.SyntaxTree.program_module.visit(IVisitor visitor)
   в PascalABCCompiler.TreeConverter.SyntaxTreeToSemanticTreeConverter.CompileInterface(compilation_unit SyntaxUnit, unit_node_list UsedUnits, List`1 ErrorsList, List`1 WarningsList, SyntaxError parser_error, Hashtable bad_nodes, using_namespace_list namespaces, Dictionary`2 docs, Boolean debug, Boolean debugging)
   в PascalABCCompiler.Compiler.CompileUnit(unit_node_list Units, unit_or_namespace SyntaxUsesUnit)
   в PascalABCCompiler.Compiler.Compile()'

task-03-1.txt (58 Байт)words.txt (606,2 КБ)

Ну вот, теперь данная ошибка просто заменилась на ошибку по ветке try/except.

Скопировал код, всё запускается на сборке 1215. Правда работает неправильно, но это уже оффтоп.

Ошибку нашла, спасибо.

по моему с такими ошибками компиляции должно быть стыдно

```

type
  arrType = array of System.Type;
  someClass = class
    function ArrTest(arr: arrType) := (arr = nil) or (arr.Length = 0); 
    procedure SetValue(value: arrType);
    begin
      if ArrTest(value) then //...
    end;
  end;
begin
end.

Хотя это лечится если тип указать явно. А если минимизировать то внутренняя ошибка компиляции

type
  arrType = array of System.Type;
  someClass = class
    function ArrTest(arr: arrType) := (arr = nil) or (arr.Length = 0);
  end;
begin
end.

Исправили. Новая версия - на сайте.

На githube ничего нет.