IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

> Настройка GPS (IDE для Ады), (разделено)
сообщение
Сообщение #1


Гость






Скачал я себе ГНАТ (Gnat GPL(без исходников, поленился все ссылки тыкать) и Win32Ada.
Скопировал я для начала в редактор кода текст из Википедии:

with Ada.Text_IO;

procedure Hello is
use Ada.Text_IO;
begin
Put_Line("Hello, world!");
end Hello.


Нажимаю "проверка синтаксиса".
[2011-01-18 21:32:02] Could not determine the project for file: C:\ADA\projects\Test\test.gpr
[2011-01-18 21:32:02] Invalid context, cannot build

В общем, я так понял, я пока с какими-то настройками не разобрался, что делать?
Заметил, что можно копировать сообщения об ошибках в буфер обмена.
Ещё, что функцию можно свернуть. После каждого сворачивания/разворачивания в конец добавляется пустая строчка (баг, есть таблетка?).
В настройках цвета не нашёл отдельного цвета для символов. Мне нравится, когда скобочки и запятые коричневые, а не чёрные.
 К началу страницы 
+ Ответить 
3 страниц V  1 2 3 >  
 Ответить  Открыть новую тему 
Ответов(1 - 19)
сообщение
Сообщение #2


Гость






Цитата
Ещё, что функцию можно свернуть. После каждого сворачивания/разворачивания в конец добавляется пустая строчка
У меня на домашней GNAT GPL 2009 такого нет. На рабочей GNAT Pro 2010 - тоже не присутствует, но там не виндовая версия. Надо будет потом посмотреть на форуме поддержки, скорее всего там уже есть сообщение о баге (если это действительно баг), и решение.

Цитата
Скопировал я для начала в редактор кода текст из Википедии:
Для начала ... Хм. Ну, вот, смотри что получается (даже если ты это уже делал, может еще кто заинтересуется) :

Запускаем GPS. Выдается вот такой диалог:
Прикрепленное изображение

Выбираем в нем создать проект при помощи Визарда, и жмем ОК. Дальше Single Project + Forward. Выбираем папку и название проекта, и дальше Forward до тех пор, пока не придем в Objects. Тут надо выбрать для Build directory ту же папку, которую выбирали при создании проекта (это не обязательно, но при отладке мне, например, удобнее, чтобы объектники и EXE не валились на системный диск, а лежали в подпапке, рядом с исходниками). Дальше ничего интересного нет, можно пробежать Forward-ом до конца, а можно сразу Apply...

Теперь имеем вот такой пустой проект:
Прикрепленное изображение

Создаем новый файл (File->New или прямо самой левой кнопкой на тулбаре), туда вписываем текст программы и сохраняем файл в рабочую папку с расширением ADB (в твоем случае процедура называется Hello, значит, hello.adb). GPR файл не трогаем вообще - это для IDE.

А вот теперь жмем "Проверку синтаксиса" (будучи именно в окне ADB-файла) :
Прикрепленное изображение

Но собрать код пока не удастся, даже когда ошибку исправишь. Для этого надо назначить главный файл проекта: Project -> Edit project properties -> Main files -> Add + hello.adb.

Вот теперь можно и собирать код...

Цитата
В настройках цвета не нашёл отдельного цвета для символов.
Теоретически знаю, что это тоже настраивается через питон, надо задать регулярное выражение, описывающее то, что ты хочешь подсвечивать , и то, каким цветом это подсвечивать. Но практически я этого никогда не делал, так что чтоб ничего не нарушить - даже не буду говорить, куда надо лезть... Если найду в техподдержке тему - скопирую решение сюда.

Если еще будут вопросы по настройке GPS - тему разделю...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Гость






Аааа.... Вот это:
Цитата
Ещё, что функцию можно свернуть. После каждого сворачивания/разворачивания в конец добавляется пустая строчка
- фича такая. Если при разворачивании блока образуется новая строка - значит, блок завершается некорректным символом. Должен всегда завершаться точкой с запятой, у тебя - просто точка. Исправишь - пустые строки добавляться перестанут. Это стандартное поведение, только что проверил, и в 2009 версии оно есть. Просто я завершающую точку уже давно не ставлю, поэтому не попадаю на подобное поведение.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Мда, название, как оказалось, у языка очень неудобное - в гугле невозможно ничего найти, сплошная эзотерика да некромантия выдаётся.
Я ничего не нашёл, всё пока делаю наугад. Какой учебник посоветуете? Что-нибудь мощное и подробное, типа Фаронова?

Пока пытаюсь понять работу основных операторов.

with Ada.Text_IO;
use Ada.Text_IO;

procedure Test is
i: integer;

begin
i := -7;
Put_Line(integer'Image(i));
i := i / 2;
Put_Line(integer'Image(i));
end Test;


Выдал -7 и -3.
То есть / для целых чисел тоже сработало.
Судя по результату, деление (увы, как и во всех других языках) прошло по правилам не математической, а компьютерной арфиметики (по правилам математики частное округляется не в сторону нуля, а в сторону минус бесконености, это делает остаток периодичной функцией, что очень удобно).
Решив проверить этот момент с оператором / на безопасность, я решил воспроизвести известную крестопроблему (у них 1/3=0, тьфу, то есть не =, а ==) и сделать так:

with Ada.Text_IO;
use Ada.Text_IO;

procedure Test is
i: integer;
j: float;

begin
i := -7;
Put_Line(integer'Image(i));
j := i / 2;
Put_Line(float'Image(j));
end Test;


Не скомпилиловалось.
j := float(i) / float(2); прошло
Безопасность в порядке, насколько это будет мешать в написании сложных выражений - не знаю.

По поводу среды. Я пока не нашёл удобную последовательность кнопок для пересбоки проекта и запуска.
Пока что я пытаюсь нажимать кнопки ALT+B+P+B+B+B+B+(кто додумался два пункта в одном подменю на одну клавишу повесть)+ENTER+SHIFT+F2. Если просто запустить, то запустится старая версия программы, такого в дельфе не было - запустить неактуальную версию из среды было невозможно, и правильно, меньше непоняток.
Как это всё настроить?
Долго думал, почему после переноса строки добавляется пробел, догадался посмотреть и заменить автоотступы с 3 на привычные 2. Жирные ключевые слова хорошо обрамляют блок, большие отступы не нужны - это только в С-образных даже 4 отступов не хватает для различения блока (им наверное скобочки плохо видны), что опровергает довод о расползании кода Паскаля в ширину, перенаправляя его против Си.

Да, тему, пожалуй, стоит разделить.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Гость






Цитата
Мда, название, как оказалось, у языка очень неудобное - в гугле невозможно ничего найти, сплошная эзотерика да некромантия выдаётся.
Можно. Добавляй в запрос что-либо из ключевых слов языка. Скажем, я добавляю "with Ada.Text_IO", и вся эзотерика улетает туда где ей и место... Остается только то, что нужно.

Учебник... Ну, пожалуй, начать следует с Гаввы, "Адское" программирование. Ада-95. Компилятор GNAT. Больше вменяемой литературы на русском языке я не видел. Скачать можешь вот отсюда, я залил себе на сайт: ada_ru.pdf (2.5 Мб, PDF). Также желательно скачать Annotated Ada Reference Manual отсюда - это и есть Стандарт языка.

Цитата
Выдал -7 и -3.
То есть / для целых чисел тоже сработало.
Разумеется. Работает для любых одинаковых типов. Кстати, существует как минимум один язык, который округляет в сторону -бесконечности. Это Питон. По крайней мере любители Питона уверяют что это именно так.

Цитата
Я пока не нашёл удобную последовательность кнопок для пересбоки проекта и запуска.
Я себе повесил Build All на Ctrl+F9 (заходишь в меню Edit->Key Shortcuts, там разворачиваешь список Build, выделяешь Build All, жмешь внизу Grab и нажимаешь желаемую комбинацию клавиш. Не пугайся, секунды на 3, может чуть больше тебе покажется, что оно зависло, IDE должна проверить, не будет ли твоя настройка конфликтовать с другими, уже существующими). Потом закрываешь этот диалог и пользуешься нормальным <Ctrl+F9> + <Shift+F2>...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Цитата
Судя по результату, деление (увы, как и во всех других языках) прошло по правилам не математической, а компьютерной арифметики (по правилам математики частное округляется не в сторону нуля, а в сторону минус бесконечности, это делает остаток периодичной функцией, что очень удобно).
Вот знаешь, за что я люблю этот язык? smile.gif Понадобилось тебе в данной конкретной программе использовать округление к -inf вместо стандартного "к нулю" - берешь и переопределяешь операцию деления:


function "/" (Left, Right : Integer'Base) return Integer'Base is
type Add_Type is array (Boolean'Range) of Integer;
Add_Value : constant Add_Type := (False => 0, True => 1);
begin
return Standard."/" (Left, Right) - Add_Value ((Left rem Right) < 0);
end "/";

pragma Inline("/");
Вот этого тебе ни С++ ни Дельфи (FPC) не дадут возможности сделать, там надо чтоб хотя бы один из типов был пользовательским, у Ады такого ограничения нет. Причем простота записи этой перегрузки (это обычная функция) дают тебе возможность написать шаблонный пакет и инстанцировать его функцией деления (по умолчанию - сделать деление из Standard, если же пользователю захотелось другого округления - пускай пишет любую функцию и передает ее в пакет. Все деления будут выполняться, используя ту функцию, которой пакет инстанцирован).
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> берешь и переопределяешь операцию деления:

Вот уж от кого, а от Ады не ожидал.
В Дельфе долго не хотели вводить, типа ради безопасности и надёжности, а тут-то...


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Надежность ни разу не страдает. Скорее наоборот. Помнишь, я в начале той темы приводил пример с перепутанными временем и расстоянием? Как вариант решения проблемы приводилось решение:

Цитата
procedure Check_Speed(T : Time; D : Distance) is
S : Speed := Speed(Integer(D) / Integer(T)); -- явное приведение типов !!!
begin
if S < SAFETY_SPEED then
Increase_Speed(S); -- Ok
end if
end Check_Speed;


Для иллюстрации - пойдет. Но в реальном проекте с ума сойдешь, постоянно приводя типы "на месте". Проще в отдельном пакете перегрузить все возможные варианты использования операторов, и использовать их:

   function "/" (Left : Distance; Right : Time) return Speed is
begin
return Speed(Integer(Left) / Integer(Right));
end "/";

procedure Check_Speed(T : Time; D : Distance) is
S : Speed := D / T;
begin
if S < SAFETY_SPEED then
Increase_Speed(S); -- Ok
end if;
end Check_Speed;

Что, здесь безопасность пострадала? Нет, код стал читабельнее... Но совершить ошибку все равно не даст.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Кстати, а как обстоит дело с размером получаемых файлов?
400 кб на консольную программку - это перебор, например.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






Ну, почему 400? Если переключить режим с Debug на Optimize, а потом зайти в Project -> Edit project properties -> Switches -> Ada linker, и там включить Strip symbols - то будет в три раза меньше. Опять же, UPX никто не отменял, после его прогона остается 60Кб.

А уже если зайти в Switches -> Binder и слинковать программу с GNAT-овским рантаймом, то простенькое консольное приложение получится вообще порядка 15-17Кб, безо всяких UPX-ов.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гость






Возникли вопросы по использованию отладчика.
Если нажать Ф5 или Ф6, то выдаётся ошибка, типа приложение не было запущено, хотя я нажимал "отладка-инициализация".

Начал читать Гавву (порадовало, что можно писать аналог const e=exp(1), в дельфи компилятор не умел вызывать функции для констант (приходилось экспоненту писать руками, типа 2.71828итд), ещё что фиксированная запятая включена в стандарт), но ещё по поводу языка возник вопрос, как пользоваться сущностями неизвестной заранее длины.
Пока единственный способ корректно их определить, который я нашёл - это заводить свой блок каждой такой переменной и инициализировать при объявлении:

declare S: string := My_Cool_Func_Which_Returns_String_With_Unknown_Length;
begin
Do_Something_Cool_With_S;
end;


(а для 10 переменных - 10 вложенных блоков?)
Только так я смог определить строку, не указывая длину.
Попытки передать string(1..10) в качестве out-параметра привели к тому, что после вывода такой строки программа завершается без сообщений.
А типа заранее завести строку неизвестной длины, а потом её присвоить (и оно само аллоцируется), как я привык в Дельфи - нельзя?
Не знаю, насколько это ограничение мешает, как я привык, пользоваться динмассивами направо и налево, передавая их по всей программе, но подход уж очень непривычный.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Гость






Цитата
Только так я смог определить строку, не указывая длину.
У Гаввы не описываются строки переменной длины, почему - не знаю, они уже были в Стандарте 95 года.

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

function F return Unbounded_String is
begin
return To_Unbounded_String("test");
end F;

ubs : Unbounded_String;

-- ...

ubs := F;
-- работай с ubs дальше...


Цитата
Если нажать Ф5 или Ф6, то выдаётся ошибка, типа приложение не было запущено, хотя я нажимал "отладка-инициализация".
Запускаешь отладчик (Debug -> Initialize), ставишь точку останова (это как в Дельфи, щелчком по точке рядом с номером строки) и запускаешь собственно программу через F2 (можешь дополнительно диалоге при старте отметить "Остановиться при входе в основную программу" - доступно только если ты установил BreakPoint - тогда тебе отладчик покажет все инициализации переменных). А уж после этого - ходи по F6...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> У Гаввы не описываются строки переменной длины, почему - не знаю, они уже были в Стандарте 95 года.

А, я уж испугался, что для цикла

for i := 0 to 255 do s := s + char(i);

придётся писать функцию с рекурсией, как во всяких прикольных языках типа Хаскела.
А если эта неограниченная строка (представляет собой, я так понял, указатель) сама делает очистку, то получается, что копирование её ни к хорошему не приведёт - копия после удаления оригинала будет указывать на порченные данные. То есть для них запрещёно присваивание (я дочитал до места про эту директиву в описании типа) и есть спец. функция копирования?


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Гость






Ты вот это имеешь в виду, что-ли:

procedure Main is
ubs2 : Unbounded_String;

procedure P is
s : Unbounded_String;
begin
s := To_Unbounded_String("just a test");
ubs2 := s;
Put_Line ("Inside : " & To_String(ubs2));
end P;

begin

P;
Put_Line ("Outside : " & To_String(ubs2));

end Main;

? Ну попробуй, запусти. К моменту вызова Put_Line основной процедуры, строки S уже не существует - это Controlled-type, при выходе из области видимости он удаляется. Однако, что будет напечатано?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Всё нормально отработало.
А в чём секрет фокуса?
Если бы я не прочитал, что переопределять := запрещено, то я бы всё понял - в присваивание зашили увеличение счётчика ссылок. Неужели разрешили?
Хранение данных произвольной длины без указателя?
Ничего не понимаю.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Гость






Для Controlled-типов есть процедура Adjust, с операцией присваивания ни разу не обязательно заморачиваться. Вот на нее и повешено увеличение счетчика ссылок.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> Для Controlled-типов есть процедура Adjust

И она неявно вызывается после присваивания (я ещё не дочитал до той главы)?

Кстати, а тут можно делать такой прикол, любимый сишниками, как рекурсивные шаблоны?


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Гость






Да, она неявно вызывается, как только объект контролируемого типа появляется слева от знака присваивания:
Цитата(ARM (7.6))
In particular, the user can define, for a controlled type, an Initialize procedure which is invoked immediately after the normal default initialization of a controlled object, a Finalize procedure which is invoked immediately before finalization of any of the components of a controlled object, and an Adjust procedure which is invoked as the last step of an assignment to a (nonlimited) controlled object.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Ух ты, тут можно хранить автоматические объекты в вариантных полях! С++ обломе!111
(ну да, с таким жёстким контролем обращения к вариантым полям вполне понятно)
Насчёт шаблонов я немного не понял. Чтобы определить, например, шаблонную функцию сложения двух чисел, мне какое ограничение надо поставить на тип? Я думал, допустимость операций над типом определится при инициализации шаблона.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Гость






Цитата
Чтобы определить, например, шаблонную функцию сложения двух чисел, мне какое ограничение надо поставить на тип?
Хитрый, да? Хочешь чтоб и is (<>) и is delta <> и is digits <> ? А нельзя в одном шаблоне это совместить. И перегружать шаблоны нельзя. Замкнутый круг, да?

Почти. Только обходится очень просто: не надо ограничивать тип, просто задай функцию, которая будет использоваться при вычислении суммы. И укажи is <> в конце, то есть, "если есть стандартная функция с таким именем для переданного типа - использовать ее".
   generic
type Element is private;
with function "+" (Left, Right : Element) return Element is <>; -- Использовать стандартную для Element
function Sum(A, B : Element) return Element;

function Sum(A, B : Element) return Element is
begin
return A + B;
end Sum;

function MySum is new Sum(Integer); -- Здесь все нормально, у Integer-а есть "+"
function OtherSum is new Sum(Float); -- Здесь тоже нормально, "+" присутствует
function TryThisSum is new Sum(String); -- А вот тут - облом. Нет предопределенного "+"

Если ты определишь оператор "+" для строк - сможешь передать его вторым параметром в шаблон, тогда эта же функция будет складывать и строки...
 К началу страницы 
+ Ответить 

3 страниц V  1 2 3 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.03.2024 9:40
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name