Elite Games - Свобода среди звезд!
.
  » Трансляторы XC->XASM и XASM->XC | страница 1
Конференция предназначена для общения пилотов. Для удобства она разделена на каналы, каждый из которых посвящен определенной игре. Пожалуйста, открывайте темы только в соответствующих каналах и после того, как убедитесь, что данный вопрос не обсуждался ранее.

Поиск | Правила конференции | Фотоальбом | Регистрация | Список пилотов | Профиль | Войти и проверить личные сообщения | Вход

   Страница 1 из 4
На страницу: 1, 2, 3, 4  След. | Все страницы
Поиск в этой теме:
Канал X2: The Threat: «Трансляторы XC->XASM и XASM->XC»
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
X-C - написание obj-программ на языке высокого уровня.

Транслятор позволяет транслировать программы, написанные на C-подобном языке, в ассеблерный код (т.е. текст), как правило inc-файл, который затем может быть откомпилирован вместе с любыми другими asm-файлами программой CheckerTwo xa_asm.exe. Пригоден для X2 и X3.

Этот C-подобный язык является языком высокого уровня. Запись свободная: пробелы, табуляции, переводы строк - незначащие символы, хотя и могут являться разделителями. Вместе с тем, отсутствует контроль типов переменных. При трансляции более или менее (на данный момент менее Улыбка ) контроллируется только наличие ошибок в тексте транслируемой программы, связанных непосредственно с самим языком X-C (т.е. синтаксические ошибки, существование локальных переменных, к которым производится обращение и т.п.), никак не проверяя существование глобальных переменных и функций, свойств и методов классов, к которым происходит обращение в программы. Тем не менее, на такие ошибки укажет xa_asm.exe при компиляции.

Также доступен для скачивания X-ASM->X-C транслятор. Производит трансляцию obj-файлов X2/X3 с ассемблера на X-C. Поддерживаются оригинальные обжи, сгенерированные Egosoft KC.


Документация по объектной модели X2. (с сайта Egosoft).

Последний obj-патч для X3 можно скачать здесь.

xa2c.rar
 Описание:
Транслятор XASM->XC версии 1.03 альфа.
 Имя файла:  xa2c.rar
 Размер файла:  87.51 KB
 Скачано:  869 раз(а)
xc.rar
 Описание:
Транслятор XC->XASM версии 1.10 бета.
 Имя файла:  xc.rar
 Размер файла:  50.44 KB
 Скачано:  909 раз(а)
xa2c.rar
 Описание:
Транслятор XASM->XC версии 1.02 альфа.
 Имя файла:  xa2c.rar
 Размер файла:  38.92 KB
 Скачано:  822 раз(а)
xc.rar
 Описание:
Транслятор XC->XASM версии 1.09 бета.
 Имя файла:  xc.rar
 Размер файла:  50.43 KB
 Скачано:  768 раз(а)
xc.rar
 Описание:
Транслятор XC->XASM версии 1.08 бета.
 Имя файла:  xc.rar
 Размер файла:  43.69 KB
 Скачано:  790 раз(а)
xa2c.rar
 Описание:
Транслятор XASM->XC версии 1.01 альфа.
 Имя файла:  xa2c.rar
 Размер файла:  38.2 KB
 Скачано:  813 раз(а)


Последний раз редактировалось: Darth Revan (19:27 17-01-2009), всего редактировалось 22 раз(а)
    Добавлено: 02:54 18-08-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Скрипты или obj-программы: преимущества и недостатки написания программ на внутреннем коде.

Преимущества:
1. Скорость. Чем больше инструкций выполняет скрипт, тем прибавка в скорости будет заметнее. Удобно использовать X-C для написания подпрограмм в скриптах (скрипт запускается относительно долго и вызов скрипта является @-командой, что может в определённых случаях быть нежелательно).
2. Удобство набора - ScE этим не славится.
3. Лёгкий доступ ко всем возможностям игры, а не только тем, что реализованы в командах ScE.

Недостатки:
1. Необходимость повышенной внимательности и аккуратности по сравнению с написанием скриптов в ScE.
2. После каждого изменения кода нужно как минимум загрузить сохранение заново (игру перезапускать не нужно).
3. Определённые трудности при загрузке обновлённых версий кода на старое сохранение.

Остановимся на последнем подробнее. Дело в том, что код при запуске не буферизуется. Допустим, мы реализовали какую-нибудь функцию, содержащую wait и запустили её. Пока она работала, игра была сохранена. Мы доработали код функции, заново перекомпилировали и загрузили сохранение. Код нашей функции продолжил выполнение после waitа на адресе следовавшей за ним команды. Могло очень повезти и адреса не сместились. В любом случае, запущенная на старом, функция продолжила работать на новом коде, что, как минимум, залог глюков.
С этим можно бороться следующим образом. Создаём глобальную переменную и зануляем её. В @-функциях проверяем перед каждым waitом (если внутри функции мы вызвали какую-нибудь Egosoftовскую функцию или функцию с гарантированно стабилизировавшимся кодом, то внутри них никаких проблем нет) и если эта переменная равна 1, выходим. Перед тем, как заменить obj-файл, устанавливаем переменную в 1 и ждём некоторое время. Затем делаем сохранение. Теперь можно заменить obj-файл. Другой вопрос, что может оказаться неудобным заново запускать нужные функции.

P.S. Есть способ лучше, см. ниже.
    Добавлено: 02:55 18-08-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Операции (в порядке убывания приоритета).

(), .(), ->() скобки, вызов функции
[] элемент массива
., -> указатель на член объекта и не только
~ битовый NOT
! логический NOT
- унарный минус
<<, >> сдвиг влево и вправо
& битовый AND
|, ^ битовые OR и XOR
*, /, % умножение, деление и остаток от деления
+, - плюс и минус.
<, <=, >, >=, ==, != операции сравнения, равно, не равно
?: тернарная опрерация
&& логический AND
|| логический OR
= присваивание
:= определение локальной переменной

В качестве разделителя между операторами выступает ;. Разделитель внутри оператора - запятая, пробел. Блоки задают фигурные скобки.

Замечания.
Можно составлять сложные выражения, содержащие внутри сравнения, присваивания и т.д., но не определения переменных.

Глобальные переменные (global variables).

Объявляются и определяются (опционально) следующим образом:
.vfixed имя = значение ; переменная с фиксированной точкой (только X3).
.vint имя = значение ; целая переменная.
.varray имя = значение ; указатель на массив.
.vtable имя = значение ; указатель на хэш-таблицу.
.vstr имя = значение ; указатель на строку.

Обращение к глобальным переменным осуществляется через оператор . с префиксом global:
global.variable_name

Классы (classes).

Определяются посредством директивы .classdef

.classdef class_name (parent class id - опционально), unique class id
описание свойств и методов (т.е. переменных и функций) класса
.endclass class_name

Если мы собираемся дополнить уже существующий класс свойствами и методами, то достаточно указать после .classdef его имя.

Переменные-свойства класса (class properties).

Определяются также, как и глобальные переменные, только внутри класса. Обращение к свойствам класса возможно только из объектов этого класса и производится через оператор ->:
this->property_name,
или
class_name->property_name,
где class_name - имя класса объекта или его предка, у которого определена переменная с именем property_name.

Глобальные функции (global functions).

Глобальные функции объявляются посредством директивы .func:
.func function_name
Затем в любом месте программы можно написать тело объявленной функции:

function_name ( список имён аргументов через запятую )
{

код
}

Например,
SampleFunction(arg1,arg2){return(arg1+arg2);}

Функции-методы класса (class methods).

Методы класса объявляются таким же образом, но внутри класса. Перед началом тела функции ставится имя класса через точку.

class_name.function_name ( список имён аргументов через запятую )
{

код
}

Например,
MyClass.SampleFunction(arg1,arg2){return(arg1+arg2);}

Обращение к методам класса производится через оператор . для объектов статичеких классов (т.е. классов, имеющих лишь один объект) и -> для нестатических.
Например,
ship->AddDefaultItems();,
где ship - объект класса TSHIP или производного от него.

sec=TCLIENT[color=blue].GetCurrentSector();
TCLIENT здесь - это константа,определённая в x2consts.h или x3consts.h и равная 2100, что совпадает с id класса TCLIENT.

Внутри методов класса доступен указатель this.

Замечания.
1. Все функции обязаны возвращать значение, хотя оно может и не использоваться вызывающей стороной.
2. Указание аргументов функций лишь задаёт им имена, если вызывающая сторона их передаст. Иными словами, аргументов на самом деле будет столько, сколько их передаст вызывающая сторона; если их передано больше, имена всё равно остаются валидными.

Встроенные функции (функции exe файла)(build-in functions).

Вызыаются без префиксного оператора. Например,
len=SE_StringLen(str);

Локальные переменные (local variables).

Локальные переменные объявляются и сразу же определяются через оператор :=. Например,
pos:=this->GetPos;

Обращение к локальным переменным осуществляется непосредственно по имени. Следует различать операции := и =. Первый из них создаёт локальную переменную и инициализирует её указанным значением, второй же копирирует значение, т.е. является операцией присваивания.

Области видимости и значения в стеке (visibility and values in the stack).

Для локальных переменных действуют области видимости. При выходе из области видимости переменная уничтожается. Области видимости (блоки) задаются операторами { и }. Имя переменной во вложенной области видимости может совпадать с именем переменной во внешней. В таком случае видна будет переменная из внутренней области.
Операторы { и } являются основным средством структурирования программы и являются обязательными при создании циклов, в условных операторах и других конструкциях. Для того, чтобы писать код, необходимо создать хотя бы одну область видимости и определить точку входа. Первый способ сделать это - просто создать функцию. Однако может потребоваться пропатчить некоторый код. В этом случае часто удобнее не создавать функцию, а сделать входную метку и добавить команду возврата в конце. Например,

MyPatch:
{

код
}
jump MyPatchRet

Области видимости позволяют автоматически удалять переменные из стека при выходе из области. Команда jump (в отличие от команд break и continue) осуществляет только безусловный переход, не предпринимая никаких действий по свобождению локальных переменных. Поэтому возврат из патча командой jump должен осуществляться после окончания области видимости патча, если только мы не желаем, чтобы в стеке остались неосвобождённые локальные переменные. При написании патча может понадобиться получить доступ к значениям, уже находящимся в стеке. Проиллюстрируем это на примере.

RunNamedFunction: (functionName:2, arg:0, argType:1, retValue:5, retType:6)
{
код
}
jump RunNamedFunctionRet;

Константы.

Числа можно писать непосредственно в коде программы. Для шестнадцатиричных, восьмеричных и двоичных чисел добавляются постфиксы h, o и b соответственно. Для десятичных чисел можно, но не обязательно, ставить префикс d. Для создания числовых констант существует директива constants. Например,

constants
{

TSUN=2008;
TPLAYER=2009;
}


Обращение к числовым константам производится непосредственно по имени. В случае конфликта имён установлена следующая последовательность приоритетов (по убыванию): локальные переменные, имена аргументов функции или поименованных значений в стеке, имена констант.

Для создания строковых констант применяется директива strings с таким же синтаксисом, как у директивы constants. Например,

strings
{

FunctionName1="MyFunction1";
FunctionName2="MyFunction2";
}


Обращение к строковых константам осуществляется через префикс string с точкой. Например,
string.FunctionName1;

Условные операторы: if.

Оператор if имеет следующий синтаксис:

if(условие)
{

код, если условие верно
}
else
{

код, если условие неверно
}

Блок с else может отсутствовать. Однооператорных if нет, впрочем, как и других конструкций - создание блоков обязательно. Единственным исключением является создание цепочек else if. В этом случае после else перед if создание блока не обязательно, т.е.

if(условие)
{

код
}
else if(
условие2)
{

код
}
else if(
условие3)
{

код
}
...
else
{

код
}

Условные операторы: switch.

Оператор switch имеет синтаксис и применение, отличающееся от используемого в C++.

switch(выражение)
{
case (
число0)
{

код
}
case (
число1)
{

код
}
...
case (
числоn)
{

код
}
}


Если указано n+1 блоков case, то числа число0, число1, ..., числоn должны быть перестановкой множества {0,1,...,n}. Иными словами, должны присутствовать все варианты выбора от 0 до n. Переход по case(0) осуществляется в случае выхода проверяемого выражения за границы множества (т.е. если значение выражения > n), поэтому этот case должен всегда присутствовать. Числа после case можно не указывать (в этом случае круглые скобки не ставятся), тогда числа в case нумеруются в естественном порядке, начиная с последнего указанного номера или нуля, если это первый блок.
В отличие от C++, в конце блока case осуществляется выход из switch. Оператор break внутри case действует как обычно, т.е. осуществляет выход не из switch, а из текущего цикла.

Операторы цикла: for.

Цикл for имеет синтаксис, схожий с C++:

for(init_compound_statement;pre_condition;post_compound_statement)
{

тело цикла
}

init_compound_statement представляет собой последовательность операторов, разделённых запятой. Локальные переменные, определённые здесь, будут, как и в C++, относиться к той области видимости, в которой создан цикл for, а не ко внутренной области тела цикла.
pre_condition является условием проверки перед началом каждой итерации цикла.
post_compound_statement представляет собой последовательность операторов, разделённых запятой, выполняющихся в конце каждой итерации цикла.

Любой из трёх параметров оператора цикла for можно опустить.

Например,

for(i:=0,j:=num-1;j>=0;i=i+1,j=j-1)
{

тело цикла
}

Операторы цикла: while.

Цикл while являтся сокращённой версией цикла for и имеет следующий синтаксис:

while(pre_condition)
{

тело цикла
}

Возможна форма цикла while без параметров, которая эквивалента форме цикла for с опущенными параметрами for(;; ) и представляет собой бесконечный цикл:

while
{

тело цикла
}

Операторы break и continue.

Оператор break осуществляет выход из текущего цикла. Возможна форма break(depth), где depth - глубина перехода, т.е. количество циклов, из которых нужно выйти. break эквивалентен break(1).
Оператор continue осуществляет переход на следующую итерацию текущего цикла (т.е. выполняются, если есть, операторы из post_compound_statement и проверяется условие). Точно так же, возможна форма continue(depth),

В связи с наличием формы break(depth) и continue(depth) операторов break и continue оператор goto отсутствует.

Директива #include

Можно подключать в программу файлы, например, заголовки с определением констант или другие файлы с целью объединения результирующего кода в один выходной файл.

Директивы . и asm.

Присутствует возможность вставлять в программу ассемблерные команды, однако в этом случае следует быть аккуратным. Возможен ожнострочный и многострочный варианты ассемблерных вставок. Однострочный вариант вставки должен начинаться с новой строки и первым значащим символом в этой строке (исключая комментарии) должна быть точка . , которая сохраняется в ассемблерном коде. Примером таких вставок являются определения классов, их членов, глобальных переменных и функций. Многострочный вариант должен начинаться с директивы asm, а текст вставки заключается в фигурные скобки. Ассемблерная вставка будет включена в результирующий код без какого-либо предварительного форматирования. Например,

asm
{

.section code, abs
$ = 0007AEA8h
jump StationsChgProdPars
.section code, con

}

Блок start.

Заключение кода в блок start позволяет запустить его в новой задаче (task), т.е. независимо от текущей задачи. При этом выполнение кода в текущей задаче продолжится сразу после блока start. Например,

function f(arg)
{

код
start
{
global.
SomeFunction(arg);
}

код
}

Комментарии (comments).

Существует два вида комментариев: однострочный // и многострочный /* ... */. Комментарии запрещены внутри блоков constants, strings и ассемблерных вставок.
    Добавлено: 02:57 18-08-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Организация связи скриптов и obj-функций.

Рассмотрим подробно, как организован вызов obj-функций из скриптов в патче ux2story13_dr2_0b. Добавлены две команды

retvalue=run function function_name with params params
init function names

Рассмотрим исходный текст файла functions.cpp, где реализованы эти команды:

Код:
#include "x2consts.h";
#include "myfunc.cpp";

.vtable g_drFunctionNames=0;
.vint g_drFunctionsNum=0;
.func InitFunctionNames;

RunNamedFunction: (functionName:2, arg:0, argType:1, retValue:5, retType:6)
 {
 retArray:=0;
 switch(global.g_drFunctionNames[functionName])
  {
  case {}
  case {retArray=global.MyFunction1(arg);}
  case {retArray=global.MyFunction2(arg);}
  }
 if(retArray)
  {
  retType=retArray[0];
  retValue=retArray[1];
  }
 else
  {
  retValue=retType=0;
  }
 }
jump RunNamedFunctionRet;

function InitFunctionNames()
 {
 global.g_drFunctionNames=SE_TableAlloc();
 global.g_drFunctionsNum=0;
 global.g_drFunctionNames[string.MyFunction1Name]=(global.g_drFunctionsNum=global.g_drFunctionsNum+1);
 global.g_drFunctionNames[string.MyFunction2Name]=(global.g_drFunctionsNum=global.g_drFunctionsNum+1);
 }
strings
 {
 MyFunction1Name=                 "MyFunction1";
 MyFunction2Name=                 "MyFunction2";
 }


Обратите внимание, что в игре помимо типа array есть тип table для хэш-таблиц. Работать с ними можно как с массивами, хотя есть и дополнительные функции. В качестве индексов массива в данном случае могут выступать не только числа (в том числе ссылки на объекты), но и строки.

Итак, создаём хэш-таблицу g_drFunctionNames и будем хранить число её элементов в переменной g_drFunctionsNum.
В коде команды init function names происходит вызов функции InitFunctionNames(). Эта функция создаёт таблицу имён и связывает с каждым из них номер, нумеруя их последовательно, начиная с единицы.
В коде команды run function производится переход по адресу с меткой RunNamedFunction. Поименуем нужные нам позиции стека:
functionName - имя функции, которую мы хотим вызвать,
arg - передаваемый аргумент,
argType - тип передаваемого аргумента,
retValue - значение, которое мы хотим возвратить в скрипт.
retType - тип возвращаемого значения.

Когда скрипты работают с переменными, они на самом деле работают с двумя числами - самим значением и его типом. Поэтому, когда мы принимаем из скрипта переменную, мы на самом деле получаем массив из двух переменных: тип и значение переменной. RunNamedFunction получает скриптовые переменные уже в "разобранном виде"; так же они и возвращаются. Часто в качестве аргумента будет передаваться массив. Скриптовые массивы в действительности преставляют собой массивы удвоенной длины, по чётным номерам которых стоят типы, а по нечётным - значения. Например, массив, который виден скрипту как (2,some_sector), на самом деле является массивом (TYPE_NUMBER,2,TYPE_SECTOR,some_sector).

Вернемся к RunNamedFunction. Для того, чтобы запустить функцию с заданным именем, достаточно по имени найти в хэш-таблице номер функции, а затем сделать switch по этому номеру, и в каждом случае вызвать функцию с нужными параметрами.

Итак, чтобы задать набор функций, которые можно запускать командой run function, нужно сделать следующее:
1. В секции strings определить желаемые имена.
2. Написать в InitFunctionNames() для каждого имени соответствующую строку (в этих строках различается только имя строковой константы).
3. В том же порядке, в котором мы добавляли имена, добавить блоки case в switch в RunNamedFunction.
4. Запустить в игре InitFunctionNames(), например, командой скрипт-редактора init function names.

Как видно, можно легко соединять вместе наборы функций, написанные различными разработчиками.

Замечание.
В X3 файл functions.cpp останется тем же, только подключать в первой строке надо x3consts.h, а строку
Код:
RunNamedFunction: (functionName:2, arg:0, argType:1, retValue:5, retType:6)

надо заменить на строку
Код:
RunNamedFunction: (functionName:2, arg:0, argType:1, retValue:4, retType:5)

(последнее связано с различием кода разбора передаваемых параметров у команд X2 и X3).
    Добавлено: 02:58 18-08-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Пример.

Предположим, мы хотим пропатчить кусок asm кода и хотим, чтобы из патча было возвращено в стек два значения. Соответственно, пишем в asm коде, где хотим вызвать патч,
jump My_Patch
и предположим, что возвращаться будем по метке My_Patch_Ret. Пишем код на XC
My_Patch:
{
retValue1:=0;
retValue2:=0;
{

Пишем здесь код патча и присваиваем значение переменным retValue1 и retValue2.
}
jump My_Patch_Ret
}
    Добавлено: 02:59 18-08-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Немного подправил транслятор, выложил документацию по X2. В первый пост.

Придумал, как обойти проблему с @-функциями на старом сохранении: waitы заносим в саму функцию, а весь код пишем в подпрограмме. Т.е. функцию, в самом грубом исполнении, пишем так:

function SomeFunction(arg)
{
while
{
ret:=SubFunction(arg);
if(ret==0)break;
TI_Delay(ret);
}
return(0);
}

Вот реализовал, для примера, масштабирование туманностей в секторе. Заодно чуть-чуть улучшил functions.cpp. Вот как выглядит код файла dr.scalenebulas.cpp.
Код:
//Пример: масштабирование всех туманностей в секторе. Единица соответствует 65536
// (т.е.множитель масштабирования имеет тип FIXED).
//Параметры: par[0] - сектор, par[1] - множитель масштабирования.
.func drScaleNebulas
function drScaleNebulas(arr)
 {
 sec:=arr[1];
 mul:=arr[3];
 nebulas:=sec->GetNebulas();
 nebula:=0;
 while(nebula=SE_TableNext(nebulas,nebula))
  {
  inst:=SA_GetInst3D(nebula->GetObjectID());
  B3D_InstSetScale(inst,mul,mul,mul);
  children:=B3D_InstGetChildren(inst);
  size:=SE_ArraySize(children);
  for(j:=0;j<size;j=j+1)
   {
   B3D_InstSetScale(children[j],mul,mul,mul);
   }
  }
 return(0);
 }

Вот результирующий inc-файл и исходники. scale_nebulas.rar.
Для установки (как и всяких последующих функций) достаточно просто скопировать functions.inc в папку с патчем и откомпилить прогой CheckerTwo.
Т.е. функции распространяются независимо от патчей и для их установки мой транслятор не требуется. Если же будут функции от нескольких авторов, то надо объедить, как я описывал, информацию из файлов functions.cpp каждого автора и оттранслировать полученный файл functions.cpp.

P.S. Кстати, взялся я ставить для исходников расширение cpp просто из удобства использования разметки. Возможно, нужно брать расширение xc или что-то подобное. Но я думаю, это не принципиально Улыбка .
    Добавлено: 23:39 18-08-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Иcправил пару небольших багов. Добавил, как это делает Игософтовский компилятор, генерацию return(0) в конце каждой функции. Так что в конце процедуры return(0) писать теперь не нужно.

Добавил трансляцию блока start.
    Добавлено: 13:04 22-08-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Обновил транслятор. Улучшил обработку блока strings, добавил возможность трансляции символьных констант (т.е. одниночных символов, например, 'A'). Можно задавать и в блоке constants.
    Добавлено: 00:33 24-08-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Добавил трансляцию строковых констант непосредственно в тексте программы. Например, global.g_drFunctionNames["pl.jump"].

Сделал более удобные синомимы некоторых команд:
create_array <=> array
create_array2 <=> array2
create_object <=> new
destroy_object <=> delete

Разрешил для обращения к свойствам объекта использовать помимо оператора -> оператор .

Добавил директиву #pragma, позволяющую менять константы, определённые в xc.ini в процессе трансляции.

Применение #pragma можно найти следующее. При оптимизации строковых костант, перед созданием новой строковой константы производится поиск, нет создано ли уже такой. Если констант очень много, то это увеличит время трансляции. Предположим, в каком-то участке программы создаётся большое количество строковых констант, которые можно исключить из поиска. Тогда пишем так:
#pragma {OptimizeStringConstants=0;}
участок программы
#pragma {OptimizeStringConstants=default;}
    Добавлено: 23:39 04-09-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Исправил баг с операторами, выполняющимися в цикле for после тела цикла, иногда приводивший к некорректности стека при переходе по continue.
    Добавлено: 03:40 22-11-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Добавил в транслятор XC следующие возможности:

1. Трансляция тернарной операции ?: Тернарная операция записывается следующим образом:
результат=условие?оператор1:оператор2
и работает так. Проверяется условие. Если оно выполнено, то результатом становится значение, которое возвращает оператор1, в противном случае - оператор2.
Например, модуль числа A можно вычислить так:
A>0?A:-A.

2. Улучшил трансляцию логических операторов && и ||. Теперь если первое условие логического И не выполнено, то второе не будет проверяться. Точно также, второе условие И не будет проверяться, если выполнено первое.

3. Добавил возможность создания нескольких меток case на один блок. Например,
case 1:
case 3:
case 5:
{
Do domething;
}

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

В целом улучшил трансляцию switch.

4. Добавил две константы в xc.ini.

1). SwitchAutoBreaks. Если 1, то после каждого case автоматичеки генерируется break. Однако стандартно инструкции case воспринимаются как метки и такой автоматической генерации не производится. Как обычно, значением константы можно управлять директивой #pragma.

2). GenerateEnd. Если 1, то в конце результирующего файла будет вставлен .end .

Также исправлена неправильная трансляция locate.
    Добавлено: 06:20 30-12-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
А всё это делалось для того, чтобы можно было транслировать восстановленный из асмы xc-код. Уфффффф, вроде удалось ретранслировать вчистую asm-код X2/X3 в XC. Пробовал запускать X2 1.4 и X3 2.0.02 на обжах, полностью транслированных из XC. Вроде работают Улыбка
    Добавлено: 06:22 30-12-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Прошу прощения. Маленький фикс на транслятор XC->XASM. Проявляется при трансляции блока, начинающегося не с имени функции, а с глобальной метки (как, например, в файле performoperation.cpp.) В общем, метка в коде дублировалась. Я просто сначала хотел сделать трансляцию некоего промежуточного между асмой и XC кода, сгенерированного Shaddie, и стал приделывать метки. Потом я решил полностью расковырять асм-код и вообще избавиться от меток. А с меткой баг и остался. Улыбка Поправил.
    Добавлено: 18:00 30-12-2006   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Исправил маленький баг в XC->XASM трансляторе, приводивший к большому перерасходу оперативной памяти. Даже страшно признаться, насколько большому... Улыбка Версия 1.06.02 альфа.
    Добавлено: 16:58 02-01-2007   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Сделал для транслятора XC-XASM - версия 1.07 альфа:
1. Возможность использовать более привычный синтаксис определения переменных. Теперь вместо оператора := можно использовать директиву var. Например, i:=0; теперь можно записать var i=0; . Доступно определение нескольких переменных через запятую: var i=0,j="X"; .
2. Исправил неправильную трансляцию конструкции switch при наличии case без параметра.
3. Несколько небольших улучшений в обработке ошибок транслятора.

Для транслятора XASM-XC - версия 1.01 альфа:
1. Определение переменных теперь выводится через var.
2. Улучшен механизм удаления лишних пар команд push 0 pop.
    Добавлено: 13:52 04-01-2007   
Shaddie
 552 EGP


Рейтинг канала: 4(60)
Репутация: 118
Сообщения: 259
Откуда: Томск
Зарегистрирован: 09.09.2004
А можно ли для транслятора XASM-XC сделать возможность вывода в стиле паскаля (по константе в ini-файле)?
Хотя бы для логических операций, например != заменить на <>.
_________________
Быстро едешь, тихо понесут...
    Добавлено: 11:21 12-01-2007   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Shaddie :
А можно ли для транслятора XASM-XC сделать возможность вывода в стиле паскаля (по константе в ini-файле)?

Если это касается только XASM->XC транслятора, то никаких проблем - могу сделать в любом виде. Итак, меняю:
= на :=
== на =
!= на <>
! на not
&,|,^ на and,or,xor
&&,|| на AND,OR
{ и } на begin и end
var придётся оставить.
Вроде всё? Завтра сделаю.
    Добавлено: 01:12 19-01-2007   
BVOne
 100 EGP

Репутация: 12
Сообщения: 496
Откуда: Кишинев, Молдова
Зарегистрирован: 07.12.2005
Интересный проект Улыбка

Darth Revan :
могу сделать в любом виде.


Сделай в виде VB?
    Добавлено: 02:43 19-01-2007   
BVOne
 100 EGP

Репутация: 12
Сообщения: 496
Откуда: Кишинев, Молдова
Зарегистрирован: 07.12.2005
Цитата:
Результатом работы программы являются два файла - имя_исходника.cpp и имя_исходника.h. Первый
файл содержит собственно исходный текст obj-файла, ретранслированный на XC, второй же файл
содержит список номеров классов, имеющихся в обрабатываемом обже.


Однако, я получил лишь:

Код:
// Generated from D:\Private Games\X2 - The Threat\l\x2intro.obj.asm, D:\Private Games\X2 - The Threat\l\x2intro.obj.out by Darth Revan's X-ASM->X-C translator v. 1.0 alpha

#include "D:\Private Games\X2 - The Threat\l\x2intro.obj.h";
#pragma {SwitchAutoBreaks=0;}
#pragma {SwitchAutoBreaks=default;}


Остальные файлы были пустыми.
Никаких ошибок не выводилось, консоль закрылась сразу.
    Добавлено: 02:53 19-01-2007   
Darth Revan
 345 EGP


Рейтинг канала: 5(150)
Репутация: 42
Сообщения: 349
Откуда: Belarus Prime
Зарегистрирован: 01.02.2006
Сначала примени дизассемблер CheckerTwo, получишь x2intro.out и x2intro.asm. А затем уже можно использовать xa2c.exe. А ты, насколько я понял, подал моему транслятору сразу obj-файл. Я проверил, у меня всё прошло без ошибок.
    Добавлено: 15:08 19-01-2007   
Канал X2: The Threat: «Трансляторы XC->XASM и XASM->XC»
На страницу: 1, 2, 3, 4  След. | Все страницы
  
Показать: 
Предыдущая тема | Следующая тема |
К списку каналов | Наверх страницы
Цитата не в тему: Я её вокальных параметров (грудь-талия-бёдра) не помню. (vetas)

  » Трансляторы XC->XASM и XASM->XC | страница 1
Каналы: Новости | Elite | Elite: Dangerous | Freelancer | Star Citizen | X-Tension/X-BTF | X2: The Threat | X3: Reunion | X3: Terran Conflict | X Rebirth | X4: Foundations | EVE Online | Orbiter | Kerbal Space Program | Evochron | VoidExpanse | Космические Миры | Онлайновые игры | Другие игры | Цифровая дистрибуция | play.elite-games.ru | ЗВ 2: Гражданская война | Творчество | Железо | Игра Мечты | Сайт
   Дизайн Elite Games V5 beta.18