Проект Оберс -> транслятор Linguage:
Ukrainian
English

- Головна - Технологія - Транслятор - Завантаження - Посилання - Про автора -

  1. Командний рядок
  2. Пакетний файл для виклику
  3. Хід трансляції
  4. Розширення мови
  5. Керування ходом трансляції та опції транслятора
  6. Розширення модуля SYSTEM
  7. Включення в програму ресурсів

Командний рядок

Командний рядок має наступний вигляд:

obers fname { -dDNAMEz }, де:

- fname - ім'я файла для трансляції вказане без розширення;
- DNAME - ім'я директиви;
- z - знак ("+" - увімкнути, "-" - вимкнути).

Транслятор завжди додає до fname розширення O2, тому файли ваших програм повинні його мати.

Зарезервовані імена директив для транслятора наступні:

  • L - додавати у вихідний файл рядки програми;
  • T - додавати у вихідний файл інформацію для трасування (нереалізоване);
  • D - додавати у вихідний файл інформацію о змінних (нереалізоване).
  • Ви можете додавати власні директиви. Вони не вплинуть на трансляцію, але будуть перенесені у вихідний файл на макроасемблері. Таким чином можна впливати на процес асемблювання програми.

    Приклади:

  • obers HELLO -dL+ -doverflow-
  • obers HELLO -dL+
  • Пакетний файл для виклику

    Коли транслятор закінчує роботу він повертає операційній системі код завершення. Код ноль означає що все гаразд, інший код - код помилки. Щоб отримувати текст пояснень на конкретний код передбачен пакетний файл obers.bat. При його використанні командний рядок має наступний вигляд:

    obers fname, де:

    - fname - ім'я файла для трансляції вказане без розширення.

    Ви мусите пам'ятати, що розширення bat в ДОС має більший пріорітет ніж com, тому для виклику транслятора треба буде застосовувати команду:

    obers.com fname

    Використання пакетного файла для роздруковки тексту помилки має одну перевагу: ви легко можете перекласти цей файл на свою національну мову, наприклад - турецьку.

    Хід трансляції

    Спочатку відкривається файл (модуль) X заданий у командному рядку. Якщо він має оператор IMPORT Y, то транслятор: зберігає поточну позицію читання в файлі, зберігає директиви трансляції, закриває поточний файл, відкриває файл модуля Y, встановлє директиви трансляції задані в командному рядку. Після обробки файла Y відбувається повернення до файла X. Вкладеність модулів обмежується тільки доступною пам'яттю. Якщо модулі X та Y імпортують модуль Z, то модуль (файл) Z буде оброблено лише перший раз, при цьому відомості про експортовані імена з нього будуть збережені. При повторному включенні модуля Z транслятор лише дозволить викликаючому модулю доступ до збережених даних.

    Якщо в програмі існують вирази в яких фігурують лише константи, то вони будуть обчислені транслятором. Наприклад:

  • x:=1+3*5-ABS(-6); i x:=10; дають однаковий код;
  • x:=1+3*5-ABS(-6)+y; i x:=10+y; дають однаковий код;
  • x:=1+3*5-y-ABS(-6); i x:=10-y; дають різний код (який поверне однаковий результат під час виконання).
  • Циклічний імпорт модулів, як відомо з визначення мови Оберон-2, заборонений. Тобто якщо в модулі X є оператор IMPORT Y, то модуль Y, не може містити оператор IMPORT X.

    Транслятор не підтримує роздільну трансляцію, тому ви повинні мати тексти всіх програмних модулів які використовуєте.

    Транслятор не вживає в вихідному файлі імен, які ви дали програмним об'єктам (змінним, підпрограмам, ...). Це пов'язано з тим, що у модулях можуть бути однакові імена, які мають різний зміст, а вихідний файл створюється один.

    Розширення мови

    Хоча розширення мови програмування і не сприяє переносу програм між різними компіляторами, але іноді воно спрощує життя. Тому остаточний вибір залишається за вами.

    "Головним розширенням" транслятора obers є підтримка імен на національних мовах. Тому ви можете, наприклад, написати такий оператор:

    сума:=доданок1+доданок2;

    До дозволених літер потрапили також зворотній апостроф (код 96) і знак підкреслення (код 95). Всі символи з 128 по 255 також є дозволеними. Мотивація розширення наступна: більша зрозумілість програми.

    Розширенням в трансляторі також є робота стандартної функції CAP(x:CHAR) - перевести літеру у верхній регістр. Проблема в тому, чим буде її аргумент: константою, чи змінною. Якщо в вашій програмі є рядок:

    буква:=CAP("я");,

    то змінній типа CHAR буде привласнено значення "Я". Кодування літер кирилиці у трансляторі відбувається за кодовою сторінкою 866 (український, російський та білоруський алфавіти). Якщо в вашій програмі є рядок:

    буква:=CAP(буква);,

    то перевід у верхній регістр буде виконано (під час виконання програми) за таблицею, яка знаходилася у файлі macro.mac. Якщо ви змінили цю таблицю, ваші результати не співпадатимуть. Мотивація цього розширення: спрощення прикладних програм.

    Транслятор obers надає можливість створювати так звані кодові підпрограми (code procedures). Це розширення рекомендується в Oakwood Guidelines, розділ 3.4. Синтаксис її визначен як:

    PROCEDURE -ProcHeading byte {"," byte};

    Отже, перед ім'ям процедури ви повинні поставити знак "-", а після заголовка процедури повинна йти через кому непорожня послідовність байтів - чисел з діапазону [0..255]. Завершується така процедура крапкою з комою. Наприклад:

    PROCEDURE -ln (x: REAL): REAL; (* log2(x)/log2(e)    *)
      0D9H,0EDH,                   (*   fldln2           *)
      0D9H,044H,024H,004H,         (*   fld dword[esp+4] *)
      0D9H,0F1H,                   (*   fyl2x            *)
      0C2H,004H,000H;              (*   ret 4            *)
    

    Коментарі в дужках не обов'язкові.

    Природньо, що такі підпрограми не є переносимими. Наприклад, наведена вище фунція ln не буде працювати в 16-розрядному режимі процесорів 80x86, крім того вона використовує інструкції сопроцесора 80x87. Мотивацією застосування таких підпрограм є білша гнучкість та ефективність кода. Кодовими процедурами можна скористатися для включення в програму ресурсів.

    Ще одним розширенням є можливість керувати ходом трансляції. Вона визначена у розділі 4.0 Oakwood Guidelines. Докладніше вона обговорюється у розділі Керування ходом трансляції та опції транслятора.

    Останнім розширенням, є підпрограми додані в модуль SYSTEM. Цей модуль включений в програму транслятора і не є зовнішнім файлом. Викликано це тим, що процедури цього модуля фактично є макросами, і їх заголовки не завжди можна визначити засобами мови. Модуль слугує меті полегшення системного програмування. Імена доданих процедур такі: Install, CLI, STI, PORTIN, PORTOUT. Докладніше додані підпрограми обговорюються у розділі Розширення модуля SYSTEM.

    Керування ходом трансляції та опції транслятора

    Дане розширення описане в Oakwood Guidelines, розділах 4.3 і 4.4. Потрібно воно для серйозних проектів, а суть є такою: у програмі є невеличкі місця які треба запрограмувати по різному в залежності від обставин. При цьому вам не хочеться створювати новий файл. У поточній реалізації транслятора obers не розрізняються опції (options) і селектори (selectors), тому що синтаксис їх використання тотожній і всі вони потрапляють у вихідний файл на асемблері. Тому надалі я писатиму леше про селектори.

    Для керування процесом трансляції потрібні ознаки - селектори. У трансляторі obers вони можуть бути задані двома способами: з командного рядка і безпосередньо в тексті. Перший способ був описаний вище. Другий спосіб має такий сінтаксис:

    <* NEW SelectorName *>

    Селектори задані в командному рядку є дійсними для всіх файлів що транслюються. Задані в тексті - тільки в поточному файлі.

    Селектори можуть мати тільки два значення: увімкнено (true) і вимкнено (false). Задати значення можна наступним чином:

    <* SelectorName+ *> - увімкнути
    <* SelectorName- *> - вимкнути

    Для перевірки селекторів і виконання дій по включенню-виключенню фрагментів текста вашої програми, слугує спеціальний умовний оператор IF. За логікою роботи він не відрізняється від штатного умовного оператора Оберона. Нижче схематично наведено його найбільш загальне використання.

    <* IF умова THEN *>
    рядки вашої програми
    <* ELSIF умова THEN *>
    рядки вашої програми
    <* ELSE *>
    рядки вашої програми
    <* END *>

    Допустимі оператори у виразі умова є ~, & i OR. Їхня дія аналогічна дії операторів Оберона з тимиж самими іменами.

    Невеличкий приклад. Припустимо, вам треба обчислювати по формулі x = x * 2. Ви знаєте, що на процесорі А швидше виконується варіант INC(x,x), а на процесорі Б - x:=ASH(x,1). Йти та компроміс ви не хочете, і мати два різних файли для однієї програми теж. Вихід такий:

    <* IF ProcA THEN *>
      INC(x,x);
    <* ELSE *>
      x:=ASH(x,1);
    <* END *>
    

    Транслюючи програму командой

    obers.com HELLO -dProcA+,

    ви матимете перший варіант кода, а командой

    obers.com HELLO -dProcA-

    - другий варіант.

    Розширення модуля SYSTEM

    За думкою авторів мови Оберон-2, в модуль SYSTEM повинні бути винесені речі, які не є стандартними для всіх платформ. У Oakwood Guidelines розділ 5.3, пропонується прийняти цей модуль за основу і розширяти коли потрібно. Я додав у модуль такі процедури.

    1. CLI - заборонити переривання;
    2. STI - дозволити переривання;
    3. Install - встановити опрацьовувач переривання;
    4. PORTIN - читати з порта;
    5. PORTOUT - записати в порт.

    Об'яви цих процедур наступні:

    PROCEDURE CLI;
    PROCEDURE STI;
    PROCEDURE Install (proc: PROCEDURE; num: байт);
    PROCEDURE PORTIN (port: LONGINT; VAR x: Type1);
    PROCEDURE PORTOUT (port: LONGINT; x: Type1);

    Під Type1 розуміється любий основний тип (крім LONGREAL), вказівник, або процедурний тип. Під байт - ціле число в диапазоні [0..255].

    Підпрограма Install виконує важливі системні речі - встановлює опрацьовувач переривання. Нагадаю, що мова Оберон-2 вимагає, щоб підпрограми які передаються як параметри, не можуть бути пов'язані з типом, бути стандартною або локальною в іншій підпрограмі.

    Включення в програму ресурсів

    Кодові підпрограми, згадані вище, можна використати для включення в програму різних ресурсів, наприклад шрифтів або малюнків. Можете застосувати для цього програму createrm.com. Її командний рядок:

    createrm resursdef,

    де resursdef - ім'я файла визначення ресурсів.

    Файл ресурсів повинен бути складеним за наступними правилами.

    1. пустий рядок, або рядок початий з пробілу, вважається коментарем і не обробляється;
    2. перший оброблений рядок складається з двох слів. Перше слово - ім'я вихідного файла без розширення. Друге слово - закінчення яке додається до констант, які визначають розмір ресурсів (розумні значення _size або _розмір);
    3. наступні рядки повинні відповідати таким правилам: перше слово - ім'я ресурса; друге слово - ім'я файла з розширенням; третє слово - зміщення в цьому файлі; четверте слово - кількість байтів (якщо задан 0, то всі байти, які залишилися до кінця).

    Наприклад, якщо задан командний рядок:

    createrm mres.res,

    а в файлі mres.res розміщено такий текст:

    proba _size
    Resurs1 text.ico 0 0
    Resurs2 text.ico 100 10H
    Resurs3 readme.txt 0 0
    

    то буде створено файл proba.O2, який матиме наступний текст (схематично):

    MODULE proba;
    CONST
      Resurs1_size- = 766;
      Resurs2_size- = 16;
      Resurs3_size- = 888;
    PROCEDURE -Resurs1-;
      000H,000H,001H,...;
    PROCEDURE -Resurs2-;
      000H,000H,001H,...;
    PROCEDURE -Resurs3-;
      020H,020H,025H,...;
    END proba.

    Вираз

    FOR i:=0 TO proba.Resurs3_size-1 DO SYSTEM.GET(SYSTEM.ADR(proba.Resurs3)+i,x) END

    послідовно зчитує всі байти файла readme.txt, для того, наприклад, щоб відобразити їх на екрані.





    Homepage: www.obers.net.ua
    EMail: admin@obers.net.ua
    18 Dec 2006 .. 14 May 2007