Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для мобильных телефонов > MidletPascal > Основной форум

Основной форум Сюда все проблемы связанные с программированием.

Ответ
 
Опции темы
Старый 27.09.2008, 21:32   #46
abcdef
Знающий
 
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений
(для 123 пользователей)
Ответ: создание MIDletPascal compiler'a

satan спасибо! за разбор исходника, сам знаю как это копаться в чужом коде, (иногда проще написать с нуля) да еще с такими до нельзя длинными переменными, но названия не решился сокращать, как в документации, чтоб понятней...
сегодня за компьютер не садился - был на дне города, погода-гадость

Администраторам форума: прошу удалить исходный текст из поста #35 т.к. он уже не актуален

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



_______PPAS1.pas_______
{parser *.pas files}
{by arT  2005}
{e-mail: [email protected]}
var
  inp, out : text;
  eof_inp  : boolean;
  s        : string;
  ch       : char;

procedure add(s : string);
begin
  writeln(out,s);  {s := s+#13#10; BlockWrite(out, s[1], Length(s));}
end;

procedure getch;
begin
  ch := #255;
  if eof_inp = false then
  begin
    read(inp,ch);          {BlockRead(inp, ch, 1);{}
    eof_inp := eof(inp);
  end;
end;

{-----}
procedure getNum;
begin
  repeat
    s := s+ch;
    getch;
  until not (ch in ['0'..'9']);
end;

procedure getHexNum;
begin
  repeat
    if ch in ['A'..'F'] then  inc(ch, (97-65));  {<- loChar}
    s := s+ch;
    getch;
  until not (ch in ['0'..'9','A'..'F','a'..'f']);
end;

procedure tok;
begin
  s := '';
  while (ch <= #32) do  getch;
  case ch of
   'A'..'Z',
   'a'..'z',
   '_'      : begin
                repeat
                  if ch in [#65..#90] then inc(ch, (97-65));
                  s := s+ch;
                  getch;
                until not (ch in ['0'..'9','_','A'..'Z','a'..'z']);
              end;
   '0'..'9' : begin
                repeat
                  getNum;
                until (ch<>'.');
              end;
   '$'      : getHexNum;
   '''','#' : begin
                repeat
                  if ch = '#' then
                  begin
                    repeat
                      s := s+ch;
                      getch;
                      if ch <> '$' then getNum
                        else getHexNum;
                    until ch <> '#';
                  end
                  else
                  begin
                    repeat
                      repeat
                        s := s+ch;
                        getch;
                      until ch = '''';
                      s := s+ch;
                      getch;
                    until ch <> '''';
                  end;
                until not (ch in ['''','#']);
              end;
   ':'      : begin
                s := ch;
                getch;
                if ch = '=' then
                begin
                  s := s+ch;
                  getch;
                end;
              end;
   '>'      : begin
                s := ch;
                getch;
                if ch = '=' then
                begin
                  s := s+ch;
                  getch;
                end;
              end;
   '<'      : begin
                s := ch;
                getch;
                if (ch = '=') or (ch = '>') then
                begin
                  s := s+ch;
                  getch;
                end;
              end;
   '.'      : begin
                s := ch;
                getch;
                if (ch = '.') or (ch = ')') then
                begin
                  s := s+ch;
                  getch;
                end;
              end;
   '('      : begin
                s := ch;
                getch;
                if (ch = '.') then
                begin
                  s := s+ch;
                  getch;
                end
                else if (ch = '*') then
                begin
                  repeat
                    while ch <> '*' do
                    begin
                      s := s+ch;
                      getch;
                      if ch = #13 then
                      begin
                        add(s);
                        s := '';
                        getch;
                        getch;
                      end;
                    end;
                    s := s+ch;
                    getch;
                  until ch = ')';
                  s := s+ch;
                  getch;
                end;
              end;
   '{'      : begin
                repeat
                  s := s+ch;
                  getch;
                  if ch = #13 then
                  begin
                    add(s);
                    s := '';
                    getch;
                    getch;
                  end;
                until ch = '}';
                s := s+ch;
                getch;
              end;
   else       begin
                s := ch;
                getch;
              end;
  end;
end;
{-----}

begin
  if paramCount <> 2 then
  begin
    writeLn('parser for PAS files'#13#$0A+
            'ver 0.0.1  by arT    e-mail: [email protected]'#13#10#10+
            'Usage:  PPAS1 <in.pas> <out.pas>');
    halt;
  end;
  s := paramStr(1);
  assign(inp, s);
  {$I-} reset(inp); {$I+}
  if IOresult = 0 then
  begin
    assign(out, ParamStr(2));
    {$I-} rewrite(out); {$I+}
    if IOresult = 0 then
    begin
      eof_inp := false;
      add('{'+s+'}');
      getch;
      repeat
        tok;
        add(s);
      until eof_inp;
      close(out);
    end
      else writeLn('Error:  can''t  create file <pas.pas>');
    close(inp);
  end
    else writeLn('Error:  file <'+s+'> not found !');
end.

_______PPAS2.pas_______
{parser "END" + ";"}
{by arT  2005}
{e-mail: [email protected]}
{поставить после каждого "END" символ ";", кроме случая "ELSE" и последнего "END"}
var
  f,f2 : text;
  s,s2 : string;
  ok   : boolean;
begin
  if paramCount<>2 then
  begin
    writeln('parse "END" + ";"'#13#$0A+
            'ver 0.0.1   by arT    e-mail: [email protected]'#13#10#10+
            'Usage:  PPAS2 <in.pas> <out.pas>');
    halt;
  end;
  assign(f,paramStr(1));
  {$I-}reset(f);{$I+}
  if IOresult<>0 then
  begin
    writeln('file <'+paramStr(1)+'> not found');
    halt;
  end;
  assign(f2,paramStr(2));
  rewrite(f2);
  ok := false;
  s2 := '';
  while not eof(f) do
  begin
    readln(f,s);
    {if ok and ((s<>'else') or (s<>'.')) then  writeln(f2,';');
    ok := (s='end');}
    if (s='end') then if (s2<>';') then writeln(f2,';');
    writeln(f2,s);
    s2 := s;
  end;
  close(f2);
  close(f);
end.

_______PPAS3.pas_______
{parser - collector}
{by arT  2005}
{e-mail: [email protected]}
const
  _vars  = 1;
  _proc  = 2;
  _prog  = 3;
var
  f1,f2 : text;
  str,s : string;
  p,t   : integer;


procedure out;
var
  i : integer;
begin
  if length(str)>0 then
  begin
    for i := 1 to p do  str := ' '+str;
    writeLn(f2,str);
  end;
  str := '';
end;


procedure add;
var
  b1,b2 : boolean;
begin
  if length(str)+length(s) > 80 then out;
  b1 := (length(str)>0) and (str[length(str)-1] in ['A'..'Z','a'..'z','0'..'9',' ']);
  b2 := (length(s)>0) and (s[1] in ['A'..'Z','a'..'z','0'..'9',' ','{']);
  if not(b1 and b2) then str := copy(str,1,length(str)-1); {remove spase in the end}
  str := str+s+' ';
end;


procedure pars;
begin
  if eof(f1) then
  begin
    add;
    out;
    close(f2);
    halt;
  end;
  readln(f1,s);
  {-----------}
  if (s='label') or (s='const') or (s='type') or (s='var') then
  begin
    t := _vars;
    out;
    p := 0;
    add;
    out;
    p := 2;
  end else
  if (s='procedure') or (s='function') then
  begin
    t := _proc;
    out;
    add;
    p := 0;
  end else
  if (s='begin') then
  begin
    out;
    add;
    if t<>_prog then p:=0;
    t:=_prog;
    out;
    inc(p,2);
    repeat
      pars;
    until (s='end');
    dec(p,2);
    pars;
    out;
  end else
  if (s='end') then
  begin
    out;
    add;
  end else
  if (s='repeat') then
  begin
    out;
    add;
    out;
    inc(p,2);
    repeat
      pars;
    until s='until';
    pars;
    dec(p,2);
  end else
  if (s='until') then
  begin
    out;
    add;
  end else
  if (s='case') then
  begin
    out;
    add;
    out;
    inc(p,2);
    repeat
      pars;
    until s='end';
    dec(p,2);
    pars;
    out;
  end else
  if (s='then') then
  begin
    add;
    repeat
      pars;
    until s=';';
  end else
  if (s='else') then
  begin
    out;
    inc(p,2);
    add;
    repeat
      pars;
    until (s=';');
    dec(p,2);
  end else
  if (s='do') then
  begin
    add;
    repeat
      pars;
    until s=';';
  end else
  if (s=';') then
  begin
    add;
    out;
  end else
  if (s[1]='{') then
  begin
    add;
    out;
  end else
  begin
    add;
  end;
end;

begin
  if paramCount <> 2 then
  begin
    WriteLn('parser - collector for PAS files'#13#$0A+
            'ver 0.0.1   by arT    e-mail: [email protected]'#13#10#10+
            'Usage:  PPAS3 <in.pas> <out.pas>');
    Halt;
  end;
  assign(f1,ParamStr(1));
  {$I-} reset(f1); {$I+}
  if IOresult = 0 then
  begin
    assign(f2,ParamStr(2));
    rewrite(f2);
    p := 0;
    str := '';
    t := _vars;
    repeat
      pars;
    until false;
  end
    else writeLn('error: file  <pas.pas> not found');
end.

после компиляции всех трех программ запускать bat-файлом:
run неформатированный_файл.pas форматированный_файл.pas

_______run.bat_______
запуск 
@echo off
echo usage: RUN  parss prog.pas  format.pas
ppas1 %1 tmp1.$$$
ppas2 tmp1.$$$ tmp2.$$$
ppas3 tmp2.$$$ %2
del tmp1.$$$
del tmp2.$$$
(Offline)
 
Ответить с цитированием
Старый 27.09.2008, 21:45   #47
abcdef
Знающий
 
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений
(для 123 пользователей)
Ответ: создание MIDletPascal compiler'a

кстати для прикола: компиляции будет поддаваться файл tmp1.$$$ ... интересно былобы посмотреть на того кто получит исходник подобного вида:

....
n
:=
word
(
swap2
(
p
,
0
)
^
)
;
write
(
'CONSTANT_Utf8-Unicode ['
,
n
,
']='
....
(Offline)
 
Ответить с цитированием
Старый 28.09.2008, 04:43   #48
satan
Нуждающийся
 
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений
(для 28 пользователей)
Re: создание MIDletPascal compiler'a

Тааааааааакккккк.... СТОП!!!
Вот оно мы и подошли к парсеру и сканеру....
И тут повторяется классическая (даж не ошибка) идея RED BOOK книги драконов и компиляторов Страуструпа и Вирта...
Для началу http://exmortis.narod.ru/ суды... Тута исходники на любой вкус, любых компилеров...

Парсер в принципе для Delphi можно выдрать из самой Delphi (класс TParser)
я в принципе так и делал...

Теперь смотри что у тя происходит, так называемый МЕТОД РЕКУРСИВНОГО СПУСКА...

procedure UpLevel;
begin
getToken; //<- берем токен кода
case Token.Name of
_Program: ;// обрабатываем сроку Program
_begin: ;// обрабатываем тело проги
_end: ;// завершаем компиляцию
end;
end;
..................

И т.д.
Метод хороший но имеет маленький нюансик... Он изночально привязан жостко к исходному языку. А нам надо (Jimon вон просил) исходный синтаксис любого языка... Поэтому луче действовать по Крэншоу, методом подъема. Смотрим логику.
Самое главное сейчас получить ассемблерный скажем байт-код Java. Потом останеться только разобрать входной язык. Поэтому надо начать с разбора ВЫРАЖЕНИЙ (Expression) вида
a=1+i-22/x+y*22;
и получать на выходе уже готовый байт-код
потом перейти к разбору переменных и типов... Это естественно заскочит в таблицы, на основе которых и соберётся заголовок.
(Offline)
 
Ответить с цитированием
Старый 28.09.2008, 08:09   #49
satan
Нуждающийся
 
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений
(для 28 пользователей)
Re: создание MIDletPascal compiler'a

Но сначал добьем дизассемблер

добавляем переменную (массив)
var
  ByteCode: array [1..209] of String = (
    'aconst_null',    'iconst_m1',      'iconst_0',            'iconst_1',        'iconst_2',            'iconst_3',
    'iconst_4',        'iconst_5',        'lconst_0',            'lconst_1',        'fconst_0',            'fconst_1',
    'fconst_2',        'dconst_0',        'dconst_1',            'bipush',          'sipush',              'ldc1',
    'ldc2',            'ldc2w',          'iload',              'lload',          'fload',              'dload',
    'aload',          'iload_0',        'iload_1',            'iload_2',        'iload_3',            'lload_0',
    'lload_1',        'lload_2',        'lload_3',            'fload_0',        'fload_1',            'fload_2',
    'fload_3',        'dload_0',        'dload_1',            'dload_2',        'dload_3',            'aload_0',
    'aload_1',        'aload_2',        'aload_3',            'iaload',          'laload',              'faload',
    'daload',          'aaload',          'baload',              'caload',          'saload',              'istore',
    'lstore',          'fstore',          'dstore',              'astore',          'istore_0',            'istore_1',
    'istore_2',        'istore_3',        'lstore_0',            'lstore_1',        'lstore_2',            'lstore_3',
    'fstore_0',        'fstore_1',        'fstore_2',            'fstore_3',        'dstore_0',            'dstore_1',
    'dstore_2',        'dstore_3',        'astore_0',            'astore_1',        'astore_2',            'astore_3',
    'iastore',        'lastore',        'fastore',            'dastore',        'aastore',            'bastore',
    'castore',        'sastore',        'pop',                'pop2',            'dup',                'dup_x1',
    'dup_x2',          'dup2',            'dup2_x1',            'dup2_x2',        'swap',                'iadd',
    'ladd',            'fadd',            'dadd',                'isub',            'lsub',                'fsub',
    'dsub',            'imul',            'lmul',                'fmul',            'dmul',                'idiv',
    'ldiv',            'fdiv',            'ddiv',                'irem',            'lrem',                'frem',
    'drem',            'ineg',            'leg',                'fneg',            'dneg',                'ishl',
    'lshl',            'ishr',            'lshr',                'iushr',          'lushr',              'iand',
    'land',            'ior',            'lor',                'ixor',            'lxor',                'iinc',
    'i2l',            'i2f',            'i2d',                'l2i',            'l2f',                'l2d',
    'f2i',            'f2l',            'f2d',                'd2i',            'd2l',                'd2f',
    'int2byte',        'int2char',        'int2short',          'lcmp',            'fcmpl',              'fcmpg',
    'dcmpl',          'dcmpg',          'ifeq',                'ifne',            'iflt',                'ifge',
    'ifgt',            'ifle',            'if_icmpeq',          'if_icmpne',      'if_icmplt',          'if_icmpge',
    'if_icmpgt',      'if_icmple',      'if_acmpeq',          'if_acmpne',      'goto',                'jsr',
    'ret',            'tableswitch',  'lookupswitch',        'ireturn',        'lreturn',            'freturn',
    'dreturn',        'areturn',        'return',              'getstatic',      'putstatic',          'getfield',
    'putfield',        'invokevirtual','invokenonvirtual',    'invokestatic',    'invokeinterface',    '',
    'new',            'newarray',        'anewarray',          'arraylength',    'athrow',              'checkcast',
    'instanceof',      'monitorenter',    'monitorexit',        'wide',            'multianewarray',      'ifnull',
    'ifnonnull',      'goto_w',          'jsr_w',              'breakpoint',      '',                    '',
    '',                '',                '',                    '',                'ret_w'
    );
немного изменяем нашу фукцию

procedure load_attribute_info;
var
  op,p1,p2: byte;
begin
и тыкаем (где разбор кода следучее)
write(#10#13,TAB);
    
    n := 0;
    while n < pCode_attribute^.code_length do
    begin
      get(p,1);
      op:= byte(p^);
      write(hexw(n),'h',TAB,hex(byte(p^)),' ');
      case byte(p^) of
          18                : // 1
                              begin
                                get(p,1); p1:=byte(p^); write(hex(byte(p^)),' ');
                                write(TAB2,ByteCode[op],' ',hex(p1),'h');
                                inc(n);
                              end;
          17,19,20,132,
          153..168,178..184,
          187,189,192,193,
          198,199,209       : // 2
                              begin
                                get(p,1); p1:=byte(p^); write(hex(byte(p^)),' ');
                                get(p,1); p2:=byte(p^); write(hex(byte(p^)),' ');
                                write(TAB,ByteCode[op],' ',hex(p1),hex(p2),'h');
                                inc(n,2);
                              end;
          197               : // 3
                              begin
                                inc(n,3);
                              end;
          185,200,201       : // 4
                              begin
                                inc(n,4);
                              end;
          171               : // 10
                              begin

                              end;
          170                : // 14
                              begin

                              end;
      else
        write(TAB2,ByteCode[byte(p^)]);
      end;
      inc(n);
      write(#10#13,TAB);
    end;
    writeln;
    writeln;
И вот мы ужо имеем дизассемблер!!!

Вот файло какое я коцал MyClass.java

interface Constants {
int NO=0;
int YES=1;
}


interface Constants2 {
int NO=0;
int YES=1;
}


class MyClass implements Constants {
public static void main (String [] args) {
int i = 0;
if (i==NO) System.out.println ("NO");
else System.out.println ("YES");
}
}

Вот шо из етого вышло
0009h   1  1 CONSTANT_Utf8-Unicode [7]  =       MyClass
0013h   2  7 CONSTANT_Class             :       1
0016h   3  1 CONSTANT_Utf8-Unicode [16] =       java/lang/Object
0029h   4  7 CONSTANT_Class             :       3
002Ch   5  1 CONSTANT_Utf8-Unicode [9]  =       Constants
0038h   6  7 CONSTANT_Class             :       5
003Bh   7  1 CONSTANT_Utf8-Unicode [4]  =       main
0042h   8  1 CONSTANT_Utf8-Unicode [22] =       ([Ljava/lang/String;)V
005Bh   9  1 CONSTANT_Utf8-Unicode [4]  =       Code
0062h  10  1 CONSTANT_Utf8-Unicode [15] =       LineNumberTable
0074h  11  1 CONSTANT_Utf8-Unicode [3]  =       out
007Ah  12  1 CONSTANT_Utf8-Unicode [21] =       Ljava/io/PrintStream;
0092h  13 12 CONSTANT_NameAndType       :       11      12
0097h  14  1 CONSTANT_Utf8-Unicode [16] =       java/lang/System
00AAh  15  7 CONSTANT_Class             :       14
00ADh  16  9 CONSTANT_Fieldref          :       15      13
00B2h  17  1 CONSTANT_Utf8-Unicode [2]  =       NO
00B7h  18  8 CONSTANT_String            :       17
00BAh  19  1 CONSTANT_Utf8-Unicode [7]  =       println
00C4h  20  1 CONSTANT_Utf8-Unicode [21] =       (Ljava/lang/String;)V
00DCh  21 12 CONSTANT_NameAndType       :       19      20
00E1h  22  1 CONSTANT_Utf8-Unicode [19] =       java/io/PrintStream
00F7h  23  7 CONSTANT_Class             :       22
00FAh  24 10 CONSTANT_Methodref         :       23      21
00FFh  25  1 CONSTANT_Utf8-Unicode [3]  =       YES
0105h  26  8 CONSTANT_String            :       25
0108h  27  1 CONSTANT_Utf8-Unicode [6]  =       <init>
0111h  28  1 CONSTANT_Utf8-Unicode [3]  =       ()V
0117h  29 12 CONSTANT_NameAndType       :       27      28
011Ch  30 10 CONSTANT_Methodref         :       4       29
0121h  31  1 CONSTANT_Utf8-Unicode [10] =       SourceFile
012Eh  32  1 CONSTANT_Utf8-Unicode [12] =       MyClass.java

013Eh           access_flags      :             32
0140h           this_class        :             2
0142h           super_class       :             4

0144h           interfaces      [1]             6 ->    [5]Constants,

0148h           field_info      [0]

014Ah           method_info     [2]
014Ch           method_info       :       0-----------
                access_flags      :             9
                name_index        :             [7]     -> main
                signature_index   :             8
                attributes_count  :             1       offs:[0154h]
0154h           GenericAttribute_info
                attribute_name    :             9       -> Code
                attribute_length  :             66
015Ah   Code:
0160h           max_stack         :             2
0160h           max_locals        :             2
015Eh           code_length       :             26

        0000h   03              iconst_0
        0001h   3C              istore_1
        0002h   1B              iload_1
        0003h   9A 00 0E        ifne 000Eh
        0006h   B2 00 10        getstatic 0010h
        0009h   12 12           ldc1 12h
        000Bh   B6 00 18        invokevirtual 0018h
        000Eh   A7 00 0B        goto 000Bh
        0011h   B2 00 10        getstatic 0010h
        0014h   12 1A           ldc1 1Ah
        0016h   B6 00 18        invokevirtual 0018h
        0019h   B1              return


0180h           GenericAttribute_info
                attribute_name    :             10      -> LineNumberTable
                attribute_length  :             22


019Ch           method_info       :       1-----------
                access_flags      :             0
                name_index        :             [27]    -> <init>
                signature_index   :             28
                attributes_count  :             1       offs:[01A4h]
01A4h           GenericAttribute_info
                attribute_name    :             9       -> Code
                attribute_length  :             33
01AAh   Code:
01B0h           max_stack         :             1
01B0h           max_locals        :             1
01AEh           code_length       :             5

        0000h   2A              aload_0
        0001h   B7 00 1E        invokenonvirtual 001Eh
        0004h   B1              return


01BBh           GenericAttribute_info
                attribute_name    :             10      -> LineNumberTable
                attribute_length  :             10



OFFSET:         01CBh
01CBh           attribute_info  [1]
01CDh           GenericAttribute_info
                attribute_name    :             31      -> SourceFile
                attribute_length  :             2

                00 20


видим дизассемблерный код

 03              iconst_0
 3C              istore_1
 1B              iload_1
 9A 00 0E        ifne 000Eh
 B2 00 10        getstatic 0010h
 12              ldc1
 12              ldc1
 B6 00 18        invokevirtual 0018h
 A7 00 0B        goto 000Bh
 B2 00 10        getstatic 0010h
 12              ldc1
 1A              iload_0
 B6 00 18        invokevirtual 0018h
 B1              return
ЗЫ...

Я тут разобрал токма двубайтовые операции, просто исходников маловат пока, если есть возможность накидайте простых исходников
с разными выпендрезами, типа исключит. ситуации и т.д... Чоб протестить.

Ассемблирование можно пустить в обратном порядке, тоисть по инструкции просто брать адрес в массиве
и собирать исходный класс.

Последний раз редактировалось satan, 28.09.2008 в 08:42.
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо satan за это полезное сообщение:
abcdef (28.09.2008), scimitar (17.11.2008)
Старый 28.09.2008, 09:12   #50
abcdef
Знающий
 
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений
(для 123 пользователей)
Ответ: создание MIDletPascal compiler'a

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

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

Синтаксис Pascal отличается тем, что все его конструкции с легкостью можно переделать в синтаксис basic или C. переобразования в обратную сторону несколько сложнее

вот ссылка на последнюю версию <pascals.zip> предлогаемого для модификации компилятора http://www.avhohlov.narod.ru/pascals.zip
(Offline)
 
Ответить с цитированием
Старый 28.09.2008, 09:32   #51
satan
Нуждающийся
 
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений
(для 28 пользователей)
Re: создание MIDletPascal compiler'a

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

Кстати Tyni C написано по другому принцпу и читаецо лехше...
Но я не настаиваю...
(Offline)
 
Ответить с цитированием
Старый 28.09.2008, 09:38   #52
abcdef
Знающий
 
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений
(для 123 пользователей)
Ответ: создание MIDletPascal compiler'a

молодец satan! держи плюсик!
вечером попробую отправить свою версию..
(Offline)
 
Ответить с цитированием
Старый 28.09.2008, 09:54   #53
satan
Нуждающийся
 
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений
(для 28 пользователей)
Re: создание MIDletPascal compiler'a

Спасиб... Тут ишо прада надо добить LineNumberTable и LocalVar...
Но ет дело техники как грица.

ХЗ. мож над исправить чо, но пока работаит

  else if s='LineNumberTable' then
  begin
      p:=get(p,2);
      lt:=word(swap2(p,0)^);
      writeln(TAB2,'line_number_table_length:',TAB,lt,#10#13);
      for i := 0 to lt-1 do
      begin
        p:=get(p,2);
        writeln(TAB3,'start_pc    :',TAB,hexw(word(swap2(p,0)^)));
        p:=get(p,2);
        writeln(TAB3,'line_number :',TAB,hexw(word(swap2(p,0)^)));
      end;
  end

Последний раз редактировалось satan, 28.09.2008 в 11:41.
(Offline)
 
Ответить с цитированием
Старый 28.09.2008, 13:07   #54
satan
Нуждающийся
 
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений
(для 28 пользователей)
Re: создание MIDletPascal compiler'a

Я хренею... Исходник виртуальной машины

do {
выбор байт кода операции
выполнение действия в зависимости от значения кода
} while (еще нужно выполнять);
Мож потом замутим?
(Offline)
 
Ответить с цитированием
Старый 29.09.2008, 06:05   #55
abcdef
Знающий
 
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений
(для 123 пользователей)
Ответ: создание MIDletPascal compiler'a

вот собрал шаблонный декомпилер, вида
<строка_название_команды> список_параметров: (1й, 2й, 3й, 4й)
в подпрограмме <disasm> - происходит разбор по типам параметров (эт для корректной обработки каждого типа, хотя можно было бы ограничиться 3-мя case условиями)

нужно подработать список команд, т.е. напротив каждой команды проставить список параметров для этой команды, я заполнил не все, может и ошибся..

satan поэкспериментируй а я на работу..
насчет эмулятора - там оч.много нужно делать библиотек, - дело не благодарное..

{$apptype console}
{$S+}
type
  tcode = record
    s : array[0..15] of char;
    b : array[0..3] of byte;
  end;
const
  nb   = 1;  {1байт целое беззнаковое}
  ns   = 2;  {1байт целое знаковое}
  nw   = 3;  {2байта целое беззнаковое}
  ni   = 4;  {2байта целое знаковое}
  cb   = 5;  {1байт индекс в константном пуле }
  cw   = 6;  {2байта индекс в константном пуле 2-х байтовой константы}
  cl   = 7;  {2байта индекс в константном пуле 2-х словной константы}
  cp   = 8;  {2байта индекс в константном пуле Получение статического поля класса  Элементом константного пула
             будет поле ссылки на статическое поле класса - полями шириной как 64-бита так и 32-бита}
  cv   = 9;  {2байта индекс в константном пуле текущего класса - сигнатура метода}
  cn   = 10; {2байта - конструирование индекса в константном пуле}
  ck   = 11; {2байта индекс на класс}
  cs   = 12; {2байта индекс на строку}
  lii  = 13; {загрузка целого из локальной переменной}
  lil  = 14; {загрузка длинного целого из локальной переменной}
  lif  = 15; {загрузка вещественного одинарной точности из локальной переменной}
  lid  = 16; {загрузка вещественного двойной точности из локальной переменной}
  lio  = 17; {загрузка объектной ссылки из локальной переменной}
  sii  = 18; {сохранение целого значения в локальной переменной}
  sil  = 19; {сохранение длинного целого в локальной переменной}
  sif  = 20; {Сохранение вещественного одинарной точности в локальной переменной}
  sid  = 21; {Сохранение двойного вещественного в локальной переменной}
  sio  = 22; {Сохранение объектной ссылки в локальной переменной}
  ac   = 23; {Увеличение локальной переменной на константу}
  of2  = 24; {16-битное знаковое смещение}
  of4  = 25; {32-битное знаковое смещение}
  ofp2 = 26; {16-битное знаковое смещение Переход на подпрограмму}
  ofp4 = 27; {32-битное знаковое смещение Переход на подпрограмму}
  rtb  = 28; {8-битный адрес Возврат из подпрограммы - адрес возврата}
  rtw  = 29; {16-битный адрес возврата}
  {-----------------------------------}
  jbc : array[0..255] of tcode = (
{00}  (s:'nop             '; b:(0,0,0,0)),      {Ничего не делает}
{01}  (s:'aconst_null     '; b:(0,0,0,0)),      {Загрузка в стек null ( пустой ссылки на объект)}
{02}  (s:'iconst_m1       '; b:(0,0,0,0)),      {Загрузка целочисленной константы -1}
{03}  (s:'iconst_0        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 0}
{04}  (s:'iconst_1        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 1}
{05}  (s:'iconst_2        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 2}
{06}  (s:'iconst_3        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 3}
{07}  (s:'iconst_4        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 4}
{08}  (s:'iconst_5        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 5}
{09}  (s:'lconst_0        '; b:(0,0,0,0)),      {Загрузка длинной целочисленной константы 0}
{0A}  (s:'lconst_1        '; b:(0,0,0,0)),      {Загрузка длинной целочисленной константы 1}
{0B}  (s:'fconst_0        '; b:(0,0,0,0)),      {Загрузка вещественного числа одинарной точности 0}
{0C}  (s:'fconst_1        '; b:(0,0,0,0)),      {Загрузка вещественного числа одинарной точности 1}
{0D}  (s:'fconst_2        '; b:(0,0,0,0)),      {Загрузка вещественного числа одинарной точности 2}
{0E}  (s:'dconst_0        '; b:(0,0,0,0)),      {Загрузка вещественного числа двойной точности 0}
{0F}  (s:'dconst_1        '; b:(0,0,0,0)),      {Загрузка вещественного числа двойной точности 1}
{10}  (s:'bipush          '; b:(nb,0,0,0)),     {1,Загрузка в стек однобайтового целого со знаком}
{11}  (s:'sipush          '; b:(ni,0,0,0)),     {2,Загрузка в стек двухбайтового целого со знаком}
{12}  (s:'ldc1            '; b:(cb,0,0,0)),     {1,Загрузка в стек элемента из константного пула}
{13}  (s:'ldc2            '; b:(cw,0,0,0)),     {2,Загрузка в стек элемента из константного пула}
{14}  (s:'ldc2w           '; b:(cl,1,0,0)),     {2,Загрузка в стек длинного целого или двойного
                                                вещественного значения из константного пула}
{15}  (s:'iload           '; b:(lii,0,0,0)),    {1,Загрузка целого из локальной переменной}
{16}  (s:'lload           '; b:(lil,0,0,0)),    {1,Загрузка длинного целого из локальной переменной}
{17}  (s:'fload           '; b:(lif,0,0,0)),    {1,Загрузка вещественного одинарной точности из локальной переменной}
{18}  (s:'dload           '; b:(lid,0,0,0)),    {1,Загрузка вещественного двойной точности из локальной переменной}
{19}  (s:'aload           '; b:(lio,0,0,0)),    {1,Загрузка объектной ссылки из локальной переменной}
{1A}  (s:'iload_0         '; b:(0,0,0,0)),      {Загрузка целого из локальной переменной 0}
{1B}  (s:'iload_1         '; b:(0,0,0,0)),      {Загрузка целого из локальной переменной 1}
{1C}  (s:'iload_2         '; b:(0,0,0,0)),      {Загрузка целого из локальной переменной 2}
{1D}  (s:'iload_3         '; b:(0,0,0,0)),      {Загрузка целого из локальной переменной 3}
{1E}  (s:'lload_0         '; b:(0,0,0,0)),      {Загрузка длинного целого из локальной переменной 0}
{1F}  (s:'lload_1         '; b:(0,0,0,0)),      {Загрузка длинного целого из локальной переменной 1}
{20}  (s:'lload_2         '; b:(0,0,0,0)),      {Загрузка длинного целого из локальной переменной 2}
{21}  (s:'lload_3         '; b:(0,0,0,0)),      {Загрузка длинного целого из локальной переменной 3}
{22}  (s:'fload_0         '; b:(0,0,0,0)),      {Загрузка вещественного одинарной точности из локальной переменной 0}
{23}  (s:'fload_1         '; b:(0,0,0,0)),      {Загрузка вещественного одинарной точности из локальной переменной 1}
{24}  (s:'fload_2         '; b:(0,0,0,0)),      {Загрузка вещественного одинарной точности из локальной переменной 2}
{25}  (s:'fload_3         '; b:(0,0,0,0)),      {Загрузка вещественного одинарной точности из локальной переменной 3}
{26}  (s:'dload_0         '; b:(0,0,0,0)),      {Загрузка вещественного двойной точности из локальной переменной 0}
{27}  (s:'dload_1         '; b:(0,0,0,0)),      {Загрузка вещественного двойной точности из локальной переменной 1}
{28}  (s:'dload_2         '; b:(0,0,0,0)),      {Загрузка вещественного двойной точности из локальной переменной 2}
{29}  (s:'dload_3         '; b:(0,0,0,0)),      {Загрузка вещественного двойной точности из локальной переменной 3}
{2A}  (s:'aload_0         '; b:(0,0,0,0)),      {Загрузка объектной ссылки из локальной переменной 0}
{2B}  (s:'aload_1         '; b:(0,0,0,0)),      {Загрузка объектной ссылки из локальной переменной 1}
{2C}  (s:'aload_2         '; b:(0,0,0,0)),      {Загрузка объектной ссылки из локальной переменной 2}
{2D}  (s:'aload_3         '; b:(0,0,0,0)),      {Загрузка объектной ссылки из локальной переменной 3}
{2E}  (s:'iaload          '; b:(0,0,0,0)),      {Загрузка целого из массива}
{2F}  (s:'laload          '; b:(0,0,0,0)),      {Загрузка длинного целого из массива}
{30}  (s:'faload          '; b:(0,0,0,0)),      {Загрузка вещественного из массива}
{31}  (s:'daload          '; b:(0,0,0,0)),      {Загрузка двойного вещественного из массива}
{32}  (s:'aaload          '; b:(0,0,0,0)),      {Загрузка объектной ссылки из массива}
{33}  (s:'baload          '; b:(0,0,0,0)),      {Загрузка байта со знаком из массива}
{34}  (s:'caload          '; b:(0,0,0,0)),      {Загрузка символа из массива}
{35}  (s:'saload          '; b:(0,0,0,0)),      {Загрузка короткого из массива}
{36}  (s:'istore          '; b:(sii,0,0,0)),    {1,Сохранение целого значения в локальной переменной}
{37}  (s:'lstore          '; b:(sil,0,0,0)),    {1,Сохранение длинного целого в локальной переменной}
{38}  (s:'fstore          '; b:(sif,0,0,0)),    {1,Сохранение вещественного одинарной точности в локальной переменной}
{39}  (s:'dstore          '; b:(sid,0,0,0)),    {1,Сохранение двойного вещественного в локальной переменной}
{3A}  (s:'astore          '; b:(sio,0,0,0)),    {1,Сохранение объектной ссылки в локальной переменной}
{3B}  (s:'istore_0        '; b:(0,0,0,0)),      {Сохранение целого в локальной переменной 0}
{3C}  (s:'istore_1        '; b:(0,0,0,0)),      {Сохранение целого в локальной переменной 1}
{3D}  (s:'istore_2        '; b:(0,0,0,0)),      {Сохранение целого в локальной переменной 2}
{3E}  (s:'istore_3        '; b:(0,0,0,0)),      {Сохранение целого в локальной переменной 3}
{3F}  (s:'lstore_0        '; b:(0,0,0,0)),      {Сохранение длинного целого в локальной переменной 0}
{40}  (s:'lstore_1        '; b:(0,0,0,0)),      {Сохранение длинного целого в локальной переменной 1}
{41}  (s:'lstore_2        '; b:(0,0,0,0)),      {Сохранение длинного целого в локальной переменной 2}
{42}  (s:'lstore_3        '; b:(0,0,0,0)),      {Сохранение длинного целого в локальной переменной 3}
{43}  (s:'fstore_0        '; b:(0,0,0,0)),      {Сохранение вещественного одинарной точности в локальной переменной 0}
{44}  (s:'fstore_1        '; b:(0,0,0,0)),      {Сохранение вещественного одинарной точности в локальной переменной 1}
{45}  (s:'fstore_2        '; b:(0,0,0,0)),      {Сохранение вещественного одинарной точности в локальной переменной 2}
{46}  (s:'fstore_3        '; b:(0,0,0,0)),      {Сохранение вещественного одинарной точности в локальной переменной 3}
{47}  (s:'dstore_0        '; b:(0,0,0,0)),      {Сохранение двойного вещественного в локальной переменной 0}
{48}  (s:'dstore_1        '; b:(0,0,0,0)),      {Сохранение двойного вещественного в локальной переменной 1}
{49}  (s:'dstore_2        '; b:(0,0,0,0)),      {Сохранение двойного вещественного в локальной переменной 2}
{4A}  (s:'dstore_3        '; b:(0,0,0,0)),      {Сохранение двойного вещественного в локальной переменной 3}
{4B}  (s:'astore_0        '; b:(0,0,0,0)),      {Сохранение объектной ссылки в локальной переменной 0}
{4C}  (s:'astore_1        '; b:(0,0,0,0)),      {Сохранение объектной ссылки в локальной переменной 1}
{4D}  (s:'astore_2        '; b:(0,0,0,0)),      {Сохранение объектной ссылки в локальной переменной 2}
{4E}  (s:'astore_3        '; b:(0,0,0,0)),      {Сохранение объектной ссылки в локальной переменной 3}
{4F}  (s:'iastore         '; b:(0,0,0,0)),      {Сохранение в целочисленном массиве}
{50}  (s:'lastore         '; b:(0,0,0,0)),      {Сохранение в массиве из длинных целых}
{51}  (s:'fastore         '; b:(0,0,0,0)),      {Сохранение в массиве из одинарных вещественных}
{52}  (s:'dastore         '; b:(0,0,0,0)),      {Сохранение в массиве из двойных вещественных}
{53}  (s:'aastore         '; b:(0,0,0,0)),      {Сохранение в массиве из объектных ссылок}
{54}  (s:'bastore         '; b:(0,0,0,0)),      {Сохранение в массиве байтов со знаком}
{55}  (s:'castore         '; b:(0,0,0,0)),      {Сохранение в символьном массиве}
{56}  (s:'sastore         '; b:(0,0,0,0)),      {Сохранение в массиве из коротких целых}
{57}  (s:'pop             '; b:(0,0,0,0)),      {Извлечение слова с вершины стека}
{58}  (s:'pop2            '; b:(0,0,0,0)),      {Извлечение двух слов с вершины стека}
{59}  (s:'dup             '; b:(0,0,0,0)),      {Дублирование слова на вершине стека}
{5A}  (s:'dup_x1          '; b:(0,0,0,0)),      {Дублирование слово на вершине стека
                                                и помещение копии в стек на два слова ниже}
{5B}  (s:'dup_x2          '; b:(0,0,0,0)),      {Дублирование вершины стека и помещение копии на три слова ниже}
{5C}  (s:'dup2            '; b:(0,0,0,0)),      {Дублирование двух слов на вершине стека}
{5D}  (s:'dup2_x1         '; b:(0,0,0,0)),      {Дублирование двух слов на вершине стека и помещение копий на два слова ниже}
{5E}  (s:'dup2_x2         '; b:(0,0,0,0)),      {Дублирование двух слов на вершине стека и помещение копий на три слова ниже}
{5F}  (s:'swap            '; b:(0,0,0,0)),      {Обмен двух слов на вершине стека}
{60}  (s:'iadd            '; b:(0,0,0,0)),      {Сложение целых}
{61}  (s:'ladd            '; b:(0,0,0,0)),      {Сложение длинных целых}
{62}  (s:'fadd            '; b:(0,0,0,0)),      {Сложение одинарных вещественных}
{63}  (s:'dadd            '; b:(0,0,0,0)),      {Сложение двойных вещественных}
{64}  (s:'isub            '; b:(0,0,0,0)),      {Вычитание целых}
{65}  (s:'lsub            '; b:(0,0,0,0)),      {Вычитание длинных целых}
{66}  (s:'fsub            '; b:(0,0,0,0)),      {Вычитание одинарных вещественных}
{67}  (s:'dsub            '; b:(0,0,0,0)),      {Вычитание двойных вещественных}
{68}  (s:'imul            '; b:(0,0,0,0)),      {Умножение целых}
{69}  (s:'lmul            '; b:(0,0,0,0)),      {Умножение длинных целых}
{6A}  (s:'fmul            '; b:(0,0,0,0)),      {Умножение одинарных вещественных}
{6B}  (s:'dmul            '; b:(0,0,0,0)),      {Умножение двойных вещественных}
{6C}  (s:'idiv            '; b:(0,0,0,0)),      {Деление целых}
{6D}  (s:'ldiv            '; b:(0,0,0,0)),      {Деление длинных целых}
{6E}  (s:'fdiv            '; b:(0,0,0,0)),      {Деление одинарных вещественных}
{6F}  (s:'ddiv            '; b:(0,0,0,0)),      {Деление двойных вещественных}
{70}  (s:'irem            '; b:(0,0,0,0)),      {Остаток от деления целых}
{71}  (s:'lrem            '; b:(0,0,0,0)),      {Остаток от деления длинных целых}
{72}  (s:'frem            '; b:(0,0,0,0)),      {Остаток от деления одинарных вещественных}
{73}  (s:'drem            '; b:(0,0,0,0)),      {Остаток от деления двойных вещественных}
{74}  (s:'ineg            '; b:(0,0,0,0)),      {Отрицание целого}
{75}  (s:'leg             '; b:(0,0,0,0)),      {Отрицание длинного целого}
{76}  (s:'fneg            '; b:(0,0,0,0)),      {Отрицание одинарного вещественного}
{77}  (s:'dneg            '; b:(0,0,0,0)),      {Отрицание двойного вещественного числа}
{78}  (s:'ishl            '; b:(0,0,0,0)),      {Сдвиг целого влево}
{79}  (s:'lshl            '; b:(0,0,0,0)),      {Сдвиг длинного целого влево}
{7A}  (s:'ishr            '; b:(0,0,0,0)),      {Арифметический сдвиг целого вправо}
{7B}  (s:'lshr            '; b:(0,0,0,0)),      {Арифметический сдвиг длинного целого вправо}
{7C}  (s:'iushr           '; b:(0,0,0,0)),      {Логический сдвиг целого вправо}
{7D}  (s:'lushr           '; b:(0,0,0,0)),      {Логический сдвиг длинного целого вправо}
{7E}  (s:'iand            '; b:(0,0,0,0)),      {Логическое И с операндами целого типа}
{7F}  (s:'land            '; b:(0,0,0,0)),      {Логическое И с операндами длинного целого типа}
{80}  (s:'ior             '; b:(0,0,0,0)),      {Логическое ИЛИ с целочисленными операндами}
{81}  (s:'lor             '; b:(0,0,0,0)),      {Логическое ИЛИ с операндами длинного целого типа}
{82}  (s:'ixor            '; b:(0,0,0,0)),      {Исключающее ИЛИ с целочисленными операндами}
{83}  (s:'lxor            '; b:(0,0,0,0)),      {Исключающее ИЛИ с операндами длинного целого типа}
{84}  (s:'iinc            '; b:(ac,ns,0,0)),    {2,Увеличение локальной переменной на константу}
{85}  (s:'i2l             '; b:(0,0,0,0)),      {Преобразование целого в длинное целое}
{86}  (s:'i2f             '; b:(0,0,0,0)),      {Целое в вещественное}
{87}  (s:'i2d             '; b:(0,0,0,0)),      {Целое в двойное вещественное}
{88}  (s:'l2i             '; b:(0,0,0,0)),      {Длинное целое в целое}
{89}  (s:'l2f             '; b:(0,0,0,0)),      {Длинное целое в вещественное}
{8A}  (s:'l2d             '; b:(0,0,0,0)),      {Длинное целое в двойное вещественное}
{8B}  (s:'f2i             '; b:(0,0,0,0)),      {Вещественное в целое}
{8C}  (s:'f2l             '; b:(0,0,0,0)),      {Вещественное в длинное целое}
{8D}  (s:'f2d             '; b:(0,0,0,0)),      {Вещественное в двойное вещественное}
{8E}  (s:'d2i             '; b:(0,0,0,0)),      {Двойное вещественное в целое}
{8F}  (s:'d2l             '; b:(0,0,0,0)),      {Двойное вещественное в длинное целое}
{90}  (s:'d2f             '; b:(0,0,0,0)),      {Двойное вещественное в вещественное}
{91}  (s:'int2byte        '; b:(0,0,0,0)),      {Целое в знаковый байт}
{92}  (s:'int2char        '; b:(0,0,0,0)),      {Целое в символ}
{93}  (s:'int2short       '; b:(0,0,0,0)),      {Целое в короткое}
{94}  (s:'lcmp            '; b:(0,0,0,0)),      {Сравнение длинных целых}
{95}  (s:'fcmpl           '; b:(0,0,0,0)),      {Сравнение вещественных одинарной точности (-1 при NaN)}
{96}  (s:'fcmpg           '; b:(0,0,0,0)),      {Сравнение вещественных одинарной точности (1 при NaN)}
{97}  (s:'dcmpl           '; b:(0,0,0,0)),      {Сравнение вещественных двойной точности(-1 при NaN)}
{98}  (s:'dcmpg           '; b:(0,0,0,0)),      {Сравнение вещественных двойной точности(1 при NaN)}
{99}  (s:'ifeq            '; b:(of2,0,0,0)),    {2,Переход, если равно 0}
{9A}  (s:'ifne            '; b:(of2,0,0,0)),    {2,Переход, если не равно 0}
{9B}  (s:'iflt            '; b:(of2,0,0,0)),    {2,Переход, если меньше 0}
{9C}  (s:'ifge            '; b:(of2,0,0,0)),    {2,Переход, если больше или равно 0}
{9D}  (s:'ifgt            '; b:(of2,0,0,0)),    {2,Переход, если больше 0}
{9E}  (s:'ifle            '; b:(of2,0,0,0)),    {2,Переход, если меньше или равно 0}
{9F}  (s:'if_icmpeq       '; b:(of2,0,0,0)),    {2,Переход, если целые равны}
{A0}  (s:'if_icmpne       '; b:(of2,0,0,0)),    {2,Переход, если целые не равны}
{A1}  (s:'if_icmplt       '; b:(of2,0,0,0)),    {2,Переход, если целое меньше 0}
{A2}  (s:'if_icmpge       '; b:(of2,0,0,0)),    {2,Переход, если целое больше или равно}
{A3}  (s:'if_icmpgt       '; b:(of2,0,0,0)),    {2,Переход, если целое больше 0}
{A4}  (s:'if_icmple       '; b:(of2,0,0,0)),    {2,Переход, если целое меньше или равно}
{A5}  (s:'if_acmpeq       '; b:(of2,0,0,0)),    {2,Переход, если ссылки на объект равны}
{A6}  (s:'if_acmpne       '; b:(of2,0,0,0)),    {2,Переход, если ссылки на объект не равны}
{A7}  (s:'goto            '; b:(of2,0,0,0)),    {2,Переход на}
{A8}  (s:'jsr             '; b:(ofp2,0,0,0)),   {2,Переход на подпрограмму}
{A9}  (s:'ret             '; b:(rtb,0,0,0)),    {1,Возврат из подпрограммы}
{AA}  (s:'tableswitch     '; b:(0,0,0,0)),      {Доступ к таблице перехода по индексу и переход}
{AB}  (s:'lookupswitch    '; b:(0,0,0,0)),      {Доступ к таблице перехода по сравнению с ключом и переход}
{AC}  (s:'ireturn         '; b:(0,0,0,0)),      {Возврат целого значения функции}
{AD}  (s:'lreturn         '; b:(0,0,0,0)),      {Возврат длинного целого значения функции}
{AE}  (s:'freturn         '; b:(0,0,0,0)),      {Возврат одинарного вещественного значения функции}
{AF}  (s:'dreturn         '; b:(0,0,0,0)),      {Возврат двойного вещественного значения функции}
{B0}  (s:'areturn         '; b:(0,0,0,0)),      {Возврат объектной ссылки из функции}
{B1}  (s:'return          '; b:(0,0,0,0)),      {Возврат(опустошающий) из процедуры}
{B2}  (s:'getstatic       '; b:(cp,0,0,0)),     {2,Получение статического поля класса}
{B3}  (s:'putstatic       '; b:(cp,0,0,0)),     {2,Установка статического поля в классе}
{B4}  (s:'getfield        '; b:(cp,0,0,0)),     {2,Перенос поля из объекта}
{B5}  (s:'putfield        '; b:(cp,0,0,0)),     {2,Установка поля в объекте}
{B6}  (s:'invokevirtual   '; b:(cv,0,0,0)),     {2,Вызывает метод экземпляра, основываясь на типе времени выполнения}
{B7}  (s:'invokenonvirtual'; b:(cv,0,0,0)),     {2,Вызывает метод экземпляра, основываясь на не виртуальном типе}
{B8}  (s:'invokestatic    '; b:(cv,0,0,0)),     {2,Вызов метода класса (статического метода)}
{B9}  (s:'invokeinterface '; b:(cv,nb,nb,0)),   {4,Вызывает метод интерфейса}
{BA}  (s:'                '; b:(0,0,0,0)),      {}
{BB}  (s:'new             '; b:(cn,0,0,0)),     {2,Создает новый объект}
{BC}  (s:'newarray        '; b:(nb,0,0,0)),     {1,atype>
                                                T_BOOLEAN=4,T_CHAR=5,T_FLOAT=6,T_DOUBLE=7,T_BYTE=8,T_SHORT=9,T_INT=9,T_LONG=11}
{BD}  (s:'anewarray       '; b:(ck,0,0,0)),     {2,Объявление нового массива из ссылок на объекты}
{BE}  (s:'arraylength     '; b:(0,0,0,0)),      {Возвращает длину массива}
{BF}  (s:'athrow          '; b:(0,0,0,0)),      {Генерация обработки или ошибки}
{C0}  (s:'checkcast       '; b:(cs,0,0,0)),     {2,Проверяет, что объект имеет данный тип}
{C1}  (s:'instanceof      '; b:(ck,0,0,0)),     {2,Определяет, имеет ли объект данный тип}
{C2}  (s:'monitorenter    '; b:(0,0,0,0)),      {Вход в контролируемую область кода}
{C3}  (s:'monitorexit     '; b:(0,0,0,0)),      {Выход из контролируемой области кода}
{C4}  (s:'wide            '; b:(nw,0,0,0)),     {1,Расширенный индекс для доступа к локальным переменным для
                                                команд загрузки, сохранения и приращени}
{C5}  (s:'multianewarray  '; b:(cn,nb,0,0)),    {3,Размещение нового многомерного массива}
{C6}  (s:'ifnull          '; b:(of2,0,0,0)),    {2,Переход, если пустой указатель}
{C7}  (s:'ifnonnull       '; b:(of2,0,0,0)),    {2,Переход, если не пустой указатель}
{C8}  (s:'goto_w          '; b:(of4,0,0,0)),    {4,Переход на (расширенный индекс)}
{C9}  (s:'jsr_w           '; b:(ofp4,0,0,0)),   {4,Переход на подпрограмму (расширенный индекс)}
{CA}  (s:'breakpoint      '; b:(0,0,0,0)),      {Остановка и передача контроля обработчику прерываний}
{CB}  (s:'                '; b:(0,0,0,0)),      {}
{CC}  (s:'                '; b:(0,0,0,0)),      {}
{CD}  (s:'                '; b:(0,0,0,0)),      {}
{CE}  (s:'                '; b:(0,0,0,0)),      {}
{CF}  (s:'                '; b:(0,0,0,0)),      {}
{D0}  (s:'                '; b:(0,0,0,0)),      {}
{D1}  (s:'ret_w           '; b:(rtw,0,0,0)),    {2,Возврат из подпрограммы (расширенный индекс)}
{D2}  (s:'                '; b:(0,0,0,0)),      {}
{D3}  (s:'                '; b:(0,0,0,0)),      {}
{D4}  (s:'                '; b:(0,0,0,0)),      {}
{D5}  (s:'                '; b:(0,0,0,0)),      {}
{D6}  (s:'                '; b:(0,0,0,0)),      {}
{D7}  (s:'                '; b:(0,0,0,0)),      {}
{D8}  (s:'                '; b:(0,0,0,0)),      {}
{D9}  (s:'                '; b:(0,0,0,0)),      {}
{DA}  (s:'                '; b:(0,0,0,0)),      {}
{DB}  (s:'                '; b:(0,0,0,0)),      {}
{DC}  (s:'                '; b:(0,0,0,0)),      {}
{DD}  (s:'                '; b:(0,0,0,0)),      {}
{DE}  (s:'                '; b:(0,0,0,0)),      {}
{DF}  (s:'                '; b:(0,0,0,0)),      {}
{E0}  (s:'                '; b:(0,0,0,0)),      {}
{E1}  (s:'                '; b:(0,0,0,0)),      {}
{E2}  (s:'                '; b:(0,0,0,0)),      {}
{E3}  (s:'                '; b:(0,0,0,0)),      {}
{E4}  (s:'                '; b:(0,0,0,0)),      {}
{E5}  (s:'                '; b:(0,0,0,0)),      {}
{E6}  (s:'                '; b:(0,0,0,0)),      {}
{E7}  (s:'                '; b:(0,0,0,0)),      {}
{E8}  (s:'                '; b:(0,0,0,0)),      {}
{E9}  (s:'                '; b:(0,0,0,0)),      {}
{EA}  (s:'                '; b:(0,0,0,0)),      {}
{EB}  (s:'                '; b:(0,0,0,0)),      {}
{EC}  (s:'                '; b:(0,0,0,0)),      {}
{ED}  (s:'                '; b:(0,0,0,0)),      {}
{EE}  (s:'                '; b:(0,0,0,0)),      {}
{EF}  (s:'                '; b:(0,0,0,0)),      {}
{F0}  (s:'                '; b:(0,0,0,0)),      {}
{F1}  (s:'                '; b:(0,0,0,0)),      {}
{F2}  (s:'                '; b:(0,0,0,0)),      {}
{F3}  (s:'                '; b:(0,0,0,0)),      {}
{F4}  (s:'                '; b:(0,0,0,0)),      {}
{F5}  (s:'                '; b:(0,0,0,0)),      {}
{F6}  (s:'                '; b:(0,0,0,0)),      {}
{F7}  (s:'                '; b:(0,0,0,0)),      {}
{F8}  (s:'                '; b:(0,0,0,0)),      {}
{F9}  (s:'                '; b:(0,0,0,0)),      {}
{FA}  (s:'                '; b:(0,0,0,0)),      {}
{FB}  (s:'                '; b:(0,0,0,0)),      {}
{FC}  (s:'                '; b:(0,0,0,0)),      {}
{FD}  (s:'                '; b:(0,0,0,0)),      {}
{FE}  (s:'                '; b:(0,0,0,0)),      {}
{FF}  (s:'                '; b:(0,0,0,0)));     {}


  CONSTANT_Class = 7;
  CONSTANT_Fieldref = 9;
  CONSTANT_Methodref = 10;
  CONSTANT_InterfaceMethodref = 11;
  CONSTANT_String = 8;
  CONSTANT_Integer = 3;
  CONSTANT_Float = 4;
  CONSTANT_Long = 5;
  CONSTANT_Double = 6;
  CONSTANT_NameAndType = 12;
  CONSTANT_Utf8 = 1;
  CONSTANT_Unicode = 2;
  {------------------------------}
  ACC_PUBLIC = 1;
  ACC_PRIVATE = 2;
  ACC_PROTECTED = 4;
  ACC_STATIC = 8;
  ACC_FINAL = 16;
  ACC_SYNCHRONIZED = 32;
  ACC_SUPER = 32;
  ACC_VOLATILE = 64;
  ACC_TRANSIENT = 128;
  ACC_NATIVE = 256;
  ACC_INTERFACE = 512;
  ACC_ABSTRACT = 1024;
  {}
type
  tfield_info = record
  access_flags : word;
  name_index : word;
  signature_index : word;
  attributes_count : word;
  {attributes[attribute_count]}
  end;
  {}
  tmethod_info = record
  access_flags : word;
  name_index : word;
  signature_index : word;
  attributes_count : word;
  {attributes[attribute_count]}
  end;
  {--атрибуты--}
  tGenericAttribute_info = record
  attribute_name : word;
  attribute_length : longInt;
  {info[attribute_length] of byte}
  end;
  {}
  tSourceFile_attribute = record
  attribute_name_index : word;
  attribute_length : longInt;
  sourcefile_index : word;
  end;
  {}
  tLineNumberTable_attribute = record
  attribute_name_index : word;
  attribute_length : longInt;
  line_number_table_length : word;
  {line_number_table[line_number_table_length] of record start_pc,line_number:word;end;}
  end;
  {}
  tConstantValue_attribute = record
  attribute_name_index : word;
  attribute_length : longInt;
  constantvalue_index : word;
  end;
  {}
  tLocalVariableTable_attribute = record
  attribute_name_index : word;
  attribute_length : longInt;
  local_variable_table_length : word;
  {local_variable_table[local_variable_table_length]}
  end;
  tLocal_variable_table = record
  start_pc : word;
  length : word;
  name_index : word;
  signature_index : word;
  slot : word;
  end;
  {}
  tExceptions_attribute = record
  attribute_name_index : word;
  attribute_length : longInt;
  number_of_exceptions : word;
  {exception_index_table[number_of_exceptions] of word}
  end;
  {}
  tInnerClasses_attribute = record
  attribute_name_index : word;
  attribute_length : longInt;
  number_of_classes : word;
  {classes[number_of_classes] of record
  inner_class_info_index : word;
  outer_class_info_index : word;
  inner_name_index : word;
  inner_class_access_flags : word;
  end}
  end;
  {}
  tSynthetic_attribute = record
  attribute_name_index : word;
  attribute_length : longInt;
  end;
  {}
  Deprecated_attribute = record
  attribute_name_index : word;
  attribute_length : longInt;
  end;
  {}
  tCode_attribute = record
  {attribute_name_index : word;
  attribute_length : longInt;{}
  max_stack : word;
  max_locals : word;
  code_length : longInt;
  end;
  {code[code_length]}
  {exception_table_length : word;{***}
  {exception_table[exception_table_length]}
  {attributes_count : word;{***}
  {attribute_info[attribute_count]}
  tException_table = record
  start_pc : word;
  end_pc : word;
  handler_pc : word;
  catch_type : word;
  end;
  {--------------------------}
  tarr = array[0..$FFFF-1] of byte;
var
  cf : record {ClassFile}
  magic : longInt;
  minor_version : word;
  major_version : word;
  constant_pool_count : word;
  cp_info :^tarr; {constant_pool[constant_pool_count - 1]}
  access_flags : word;
  this_class : word;
  super_class : word;
  interfaces_count : word;
  interfaces :^tarr; {[interfaces_count]}
  fields_count : word;
  field_info :^tarr; {fields[fields_count]}
  methods_count : word;
  method_info :^tarr; {methods[methods_count]}
  attributes_count : word;
  attribute_info :^tarr; {attributes[attribute_count]}
end;

var
  f : file;
  i,j,n,rc : integer; {longInt;}
  s : string;
  tag : byte;
  p :^byte;
  pfield_info :^tfield_info;
  pmethod_info :^tmethod_info;
  pGenericAttribute_info :^tGenericAttribute_info;
  pCode_attribute :^tCode_attribute;
  pException_table :^tException_table;
  pexception_table_length :^word;
  pattributes_count :^word;
  pLocalVariableTable_attribute :^tLocalVariableTable_attribute;
  pLocal_variable_table :^tLocal_variable_table;


function hex(b : byte) : string;
const
  h : array[0..$F] of char = '0123456789ABCDEF';
begin
  hex := h[b shr 4]+h[b and $F];
end;


function hex2(w : word) : string;
begin
  hex2 := hex(hi(w))+hex(lo(w));
end;

function hex4(l : longInt) : string;
var        {longInt to hexLongInt}
  b : array[0..3] of byte absolute l;
Begin
  hex4 := hex(b[3])+hex(b[2])+hex(b[1])+hex(b[0]);
End;


function get(p : pointer; count : integer) : pointer;
var
  n : integer;
begin
  blockRead(f,p^,count,n);
  inc(longInt(p),n); {pasc}
  inc(rc,n);
  get := p; {get := ptr(cardinal(p)+count); //delphi}
end;

function swap2(p : pointer; offs : integer) : pointer;
var
  b1,b2 :^byte;
  b : byte;
begin
  dec(longInt(p),offs+1);
  b1 := p;
  dec(longInt(p));
  b2 := p;
  b := b1^; b1^ := b2^; b2^ := b;
  swap2 := p;
end;


function swap4(p : pointer; offs : integer) : pointer;
var
  w1,w2 : ^word;
  w : word;
begin
  w1 := swap2(p,0);
  w2 := swap2(w1,0);
  w := w1^; w1^ := w2^; w2^ := w;
  swap4 := w2;
end;


function pconst(i : integer) : pointer;
var
  w :^word;
  p :^byte;
begin
  p := nil;
  if (i>=1) and (i<cf.constant_pool_count-1) then
  begin
    p := @cf.cp_info^;
    while i>=1 do
    begin
      case p^ of
        CONSTANT_Class:
          inc(p,1+2);
        CONSTANT_Fieldref,CONSTANT_Methodref,CONSTANT_InterfaceMethodref:
          inc(p,1+4);
        CONSTANT_String:
          inc(p,1+2);
        CONSTANT_Integer,CONSTANT_Float:
          inc(p,1+4);
        CONSTANT_Long:
          inc(p,1+8 );
        CONSTANT_NameAndType:
          inc(p,1+4);
        CONSTANT_Utf8, CONSTANT_Unicode:
          begin {null=$0000, 1b=$0001-$007F,2b=$0008-$07FF,3b=$0800-$FFFF{}
            inc(p);
            w := @p^;
            inc(p,2);
            inc(p,w^)
          end;
        else begin p := nil; i := 0; end;
      end;
      dec(i);
    end;
  end;
  pconst := p;
end;

function getConstStr(index : word) : string;
var
  s : string;
  j : word;
  p :^byte;
  w :^word;
begin
  s := '';
  p := pconst(index);
  if p<>nil then
  case p^ of
    CONSTANT_Class:
      begin
        w := @p^;
        inc(w);
        p := pconst(w^);
      end;
    CONSTANT_Fieldref,CONSTANT_Methodref,CONSTANT_InterfaceMethodref:
      begin
        w := @p^;
        inc(w);
        p := pconst(w^);
      end;
    CONSTANT_String:
      begin
        w := @p^;
        inc(w);
        p := pconst(w^);
      end;
    CONSTANT_NameAndType:
      begin
        w := @p^;
        inc(w);
        p := pconst(w^);
      end;
  end;
  {null=$0000, 1b=$0001-$007F,2b=$0008-$07FF,3b=$0800-$FFFF{}
  if p<>nil then
    if (p^ in [CONSTANT_Utf8, CONSTANT_Unicode]) then
    begin
      inc(p);
      w := @p^;
      inc(p,2);
      for j := 0 to w^-1 do
      begin
        s := s+chr(p^);
        inc(p);
      end;
    end;
  getConstStr := s;
end;

{-------------------}
procedure disasm;
var
  op,k : byte;
begin
  get(p,1);
  op:=byte(p^);
  inc(p);
  write(hex(op),' '+jbc[op].s+' ');
  for k:=0 to 3 do
  case jbc[op].b[k] of
    0: begin end;
    nb:   {1байт целое беззнаковое}
      begin
        write(hex(byte(get(p,1)^)),' ');
        inc(p);
      end;
    ns:   {1байт целое знаковое}
      begin
        write(hex(byte(get(p,1)^)),' ');
        inc(p);
      end;
    nw:   {2байта целое беззнаковое}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    ni:   {2байта целое знаковое}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cb:   {1байт индекс в константном пуле }
      begin
        write(hex(byte(get(p,2)^)),' ');
        inc(p,1);{}
{       write(hexw(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);{}
      end;
    cw:   {2байт индекс в константном пуле 2-х байтовой константы}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cl:   {2байт индекс в константном пуле 2-х словной константы}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cp:   {2байт индекс в константном пуле Получение статического поля класса  Элементом константного пула
          будет поле ссылки на статическое поле класса - полями шириной как 64-бита так и 32-бита}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cv:   {2байт индекс в константном пуле текущего класса - сигнатура метода}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cn:   {2байт - конструирование индекса в константном пуле}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    ck:   {2байт  индекс на класс}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cs:   {2байт  индекс на строку}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    lii:  {загрузка целого из локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    lil:  {загрузка длинного целого из локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    lif:  {загрузка вещественного одинарной точности из локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    lid:  {загрузка вещественного двойной точности из локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    lio:  {загрузка объектной ссылки из локальной переменной}
      begin
{       write(hex(byte(get(p,1)^)),' ');
        inc(p,1);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    sii:  {сохранение целого значения в локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    sil:  {сохранение длинного целого в локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    sif:  {Сохранение вещественного одинарной точности в локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    sid:  {Сохранение двойного вещественного в локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    sio:  {Сохранение объектной ссылки в локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    ac:   {Увеличение локальной переменной на константу}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    of2:  {16-битное знаковое смещение}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    of4:  {32-битное знаковое смещение}
      begin
        write(hex4(longInt(swap4(get(p,4),0)^)),' ');
        inc(p,4);
      end;
    ofp2: {16-битное знаковое смещение Переход на подпрограмму}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    ofp4: {32-битное знаковое смещение Переход на подпрограмму}
      begin
        write(hex4(longInt(swap4(get(p,4),0)^)),' ');
        inc(p,4);
      end;
    rtb:  {8-битный адрес Возврат из подпрограммы - адрес возврата}
      begin
        write(hex(word(get(p,1)^)),' ');
        inc(p);
      end;
    rtw:  {16-битный адрес возврата}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    else writeln('Error: str:[', op, ',', k, ']=', jbc[op].b[k]);
  end;
end;
{-------------------}

procedure load_const;
begin
  get(p,1);
  tag := p^;
  inc(p);
  write(tag:2,' ');
  case tag of
    CONSTANT_Class:
      begin
        p := get(p,2);
        write('CONSTANT_Class:              ',word(swap2(p,0)^));
      end;
    CONSTANT_Fieldref,CONSTANT_Methodref,CONSTANT_InterfaceMethodref:
      begin
        case tag of
          CONSTANT_Fieldref : write('CONSTANT_Fieldref:           ');
          CONSTANT_Methodref: write('CONSTANT_Methodref:          ');
          CONSTANT_InterfaceMethodref: write('CONSTANT_InterfaceMethodref:');
        end;
        p := get(p,4);
        write(word(swap2(p,2)^),' ',word(swap2(p,0)^));
      end;
    CONSTANT_String:
      begin
        p := get(p,2);
        write('CONSTANT_String:             ',word(swap2(p,0)^));
      end;
    CONSTANT_Integer,CONSTANT_Float:
      begin
        case tag of
          CONSTANT_Integer  : write('CONSTANT_Integer:           ');
          CONSTANT_Float    : write('CONSTANT_Float:             ');
        end;
        p := get(p,4);
        write(longInt(swap4(p,0)^));
      end;
    CONSTANT_Long,CONSTANT_Double:
      begin
        case tag of
          CONSTANT_Long: write('CONSTANT_Integer:          ');
          CONSTANT_Double: write('CONSTANT_Double:         ');
        end;
        p := get(p,8 );
        write('_hi:',longInt(swap4(p,4)^),'_lo:',longInt(swap4(p,0)^));
        inc(i);
      end;
    CONSTANT_NameAndType:
      begin
        p := get(p,4);
        write('CONSTANT_NameAndType:       ',word(swap2(p,2)^),' ',word(swap2(p,0)^));
      end;
    CONSTANT_Utf8,CONSTANT_Unicode:
      begin {null=$0000, 1b=$0001-$007F,2b=$0008-$07FF,3b=$0800-$FFFF{}
        p := get(p,2); {length}
        n := word(swap2(p,0)^);
        write('CONSTANT_Utf8-Unicode [',n:3,']','=');
        for j := 0 to n-1 do
        begin
          get(p,1);
          write(chr(p^));
          inc(p);
        end;
      end;
    else if tag<>0 then
    begin
      write('error:',tag);
      halt;
    end;
  end;
  writeln;
end;


procedure load_attribute_info;
var
  offs,start :^byte;
begin
  writeln(hex4(rc), 'h  genericAttribute_info');
  p:=get(p,sizeof(pGenericAttribute_info^));
  pGenericAttribute_info:=swap2(swap4(p,0),0);
  s := getConstStr(pGenericAttribute_info^.attribute_name-1);
  writeln('       attribute_name:  ',pGenericAttribute_info^.attribute_name,' -> ',s);
  writeln('       attribute_length:',pGenericAttribute_info ^.attribute_length);
  if s='Code' then
  begin
    writeln(hex4(rc), 'h  Code:');
    p := get(p,sizeof(pCode_attribute^));
    pCode_attribute := swap2(swap2(swap4(p,0),0),0);
    writeln(hex4(rc-sizeof(pCode_attribute^.max_stack)),
    'h  max_stack:  ', pCode_attribute^.max_stack);
    writeln(hex4(rc-sizeof(pCode_attribute^.max_locals)),
    'h  max_locals: ', pCode_attribute^.max_locals);
    writeln(hex4(rc-sizeof(pCode_attribute^.code_length)),
    'h  code_length:', pCode_attribute^.code_length);
    start := @p^;
    offs  := @p^;
    inc(longInt(offs), pCode_attribute^.code_length);
    writeln('_______DISASSEMBLE-START_______');
    while (longInt(p) < longInt(offs)) do
    begin
      write(hex4(longInt(p)-longInt(start)),'h   ');
      disasm;
      writeln;
    end;
    writeln('________DISASSEMBLE-END________');
(*  writeln;
    n := 0;
    while n < pCode_attribute^.code_length do
    begin
      write(hexw(n),'h'#9, hex(byte(p^)),' ');
      op:=byte(get(p,1)^);
      inc(p);
      case byte(p^) of
{1}     18:
          begin
            get(p,1); p1:=byte(p^); write(hex(byte(p^)),' ');
            write(TAB2,ByteCode[op],' ',hex(p1),'h');
            inc(n);
          end;
{2}     17,19,20,132,153..168,178..184,187,189,192,193,198,199,209:
          begin
            get(p,1); p1:=byte(p^); write(hex(byte(p^)),' ');
            get(p,1); p2:=byte(p^); write(hex(byte(p^)),' ');
            write(TAB,ByteCode[op],' ',hex(p1),hex(p2),'h');
            inc(n,2);
          end;
{3}     197:
          begin
            inc(n,3);
          end;
{4}     185,200,201:
          begin
            inc(n,4);
          end;
{10}    171:
          begin
          end;
{14}    170:
          begin
          end;
        else write('  ',ByteCode[byte(p^)]);
      end;
      writeln;
      inc(n);
    end;
    {for n := 0 to pCode_attribute^.code_length-1 do
    begin
      get(p,1);
      write(hex(byte(p^)),' ');
      if (n mod 8)=0 then writeln;
    end;{}*)

    writeln;
    p := get(p,sizeof(pexception_table_length^));
    pexception_table_length:=swap2(p,0);
    writeln(hex4(rc-sizeof(pexception_table_length^)),'h  pexception_table [',pexception_table_length^,']=');
    for n := 0 to pexception_table_length^-1 do
    begin
      writeln(hex4(rc), 'h  exception_table:',i,'_');
      p := get(p,sizeof(pException_table^));
      pException_table := swap2(swap2(swap2(swap2(p,0),0),0),0);
      writeln('     start_pc:  ', pException_table^.start_pc);
      writeln('     end_pc:    ', pException_table^.end_pc);
      writeln('     handler_pc:', pException_table^.handler_pc);
      writeln('     catch_type:', pException_table^.catch_type);
    end;
    p := get(p,sizeof(pattributes_count^));
    pattributes_count :=swap2(p,0);
    writeln('     attributes [',pAttributes_count^,']=');
    for n := 0 to pAttributes_count^-1 do
    begin
      writeln(hex4(rc),'h  attributes_info :',n,'_');
      load_attribute_info;
    end;
  end
  else if s='LocalVariableTable' then
  begin
    writeln(hex4(rc), 'h  LocalVariableTable');
    p := get(p,sizeof(pLocalVariableTable_attribute^));
    pLocalVariableTable_attribute := swap2(swap4(swap2(p,0),0),0);
    writeln(hex4(rc-sizeof(pLocalVariableTable_attribute^.attribute_name_index)),
    '     attribute_name_index:       ', pLocalVariableTable_attribute^.attribute_name_index);
    writeln(hex4(rc-sizeof(pLocalVariableTable_attribute^.attribute_length)),
    '     attribute_length:           ', pLocalVariableTable_attribute^. attribute_length);
    writeln(hex4(rc-sizeof(pLocalVariableTable_attribute^.local_variable_table_length)),
    '     local_variable_table_length:', pLocalVariableTable_attribute^.local_variable_table_length);
    for n := 0 to pLocalVariableTable_attribute^.local_variable_table_length-1 do
    begin
      writeln(hex4(rc),'h  localVariableTable_attribute',i,'_');
      p := get(p,sizeof(pLocal_variable_table^));
      pLocal_variable_table := swap2(swap2(swap2(swap2(swap2(p,0),0),0),0),0);
      writeln('     start_pc:       ', pLocal_variable_table^.start_pc);
      writeln('     length:         ', pLocal_variable_table^.length);
      writeln('     name_index:     ', pLocal_variable_table^.name_index);
      writeln('     signature_index:', pLocal_variable_table^. signature_index);
      writeln('     slot:           ', pLocal_variable_table^.slot);
    end;
  end
  else if s='LineNumberTable' then
  begin
    writeln(hex4(rc),'h  LineNumberTable [', pGenericAttribute_info^.attribute_length,']=');
    for n := 0 to pGenericAttribute_info^.attribute_length-1 do
    begin
      get(p,1);
      {write(hex(byte(p^)),' ');{}
      inc(p);
    end;
    {p:=get(p,2);
    n:=word(swap2(p,0)^);
    writeln(hex4(rc),'h  line_number_table [',n,']=');
    while n>0 do
    begin
      writeln('     start_pc    :', hexw(word(swap2(get(p,2),0)^)));
      inc(p,2);
      writeln('     line_number :', hexw(word(swap2(get(p,2),0)^)));
      inc(p,2);
      dec(n);
    end;}
  end
  {if s='SourceFile' then
  begin
  end{}
  else {don't know... skip atributes}

  begin
    writeln(hex4(rc),'h  ANY_BLOCK [', pGenericAttribute_info^.attribute_length,']=');
    for n := 0 to pGenericAttribute_info^.attribute_length-1 do
    begin
      get(p,1);
      write(' ',hex(byte(p^)));
      if ((n+1) mod 16)=0 then writeln;
      inc(p);
    end;
  end;
  writeln;
end;


procedure load_interfaces;
begin
  p := get(p,2);
  write(word(swap2(p,0)^),',');
end;


procedure load_field_info;
begin
  p := get(p,sizeof(pfield_info^));
  pfield_info := swap2(swap2(swap2(swap2(p,0),0),0),0);
  writeln('       access_flags:    ',pfield_info^.access_flags) ;
  writeln('       name_index:      ',pfield_info^.name_index);
  writeln('       signature_index: ',pfield_info^.signature_index);
  writeln('       attributes_count:',pfield_info^.attributes_count);
  for j := 0 to pfield_info^.attributes_count-1 do
  begin
    writeln(hex4(rc),'h  attributes_info :',j,'_');
    load_attribute_info;
  end;
end;


procedure method_info;
begin
  p := get(p,sizeof(pmethod_info^));
  pmethod_info := swap2(swap2(swap2(swap2(p,0),0),0),0);
  s := getConstStr(pmethod_info^.name_index-1);
  writeln('       access_flags:    ',pmethod_info^.access_flags );
  writeln('       name_index:     [',pmethod_info^.name_index,'] -> ',s);
  writeln('       signature_index: ',pmethod_info^.signature_index);
  writeln('       attributes_count:',pmethod_info^.attributes_count);
  for j := 0 to pmethod_info^.attributes_count-1 do
  begin
    writeln(hex4(rc),'h  attributes_info :',j,'_');
    load_attribute_info;
  end;
end;


begin
  getMem(cf.cp_info,            $FFFF);
  getMem(cf.interfaces,         $7FFF);
  getMem(cf.field_info,         $FFFF);
  getMem(cf.method_info,        $FFFF);
  getMem(cf.attribute_info,     $FFFF);
  fillChar(cf.cp_info^,         $FFFF, 0);
  fillChar(cf.interfaces^,      $7FFF, 0);
  fillChar(cf.field_info^,      $FFFF, 0);
  fillChar(cf.method_info^,     $FFFF, 0);
  fillChar(cf.attribute_info^,  $FFFF, 0);
  assign(f,'fw.cla');
  {cf.magic := $CAFEBABE; cf.minor_version := $0000; cf.major_version := $002E;
  rewrite(f,1);
  blockWrite(f,cf.magic,sizeof(cf.magic),n);
  blockWrite(f,cf.minor_version,sizeof(cf.minor_version),n);
  blockWrite(f,cf.major_version,sizeof(cf.major_version),n);{...}
  reset(f,1);
  rc := 0;
  swap4(get(@cf.magic,sizeof(cf.magic)),0);
  swap2(get(@cf.minor_version,sizeof(cf.minor_version)),0);
  swap2(get(@cf.major_version,sizeof(cf.major_version)),0);
  swap2(get(@cf.constant_pool_count,sizeof(cf.constant_pool_count)),0);
  p := @cf.cp_info^;
  i := 1;
  while i < cf.constant_pool_count do
  begin
    write(hex4(rc-1),'h ',i:3,' ');
    load_const;
    inc(i);
  end;
  writeln;
  swap2(get(@cf.access_flags,sizeof(cf.access_flags)),0);
  writeln(hex4(rc-sizeof(cf.access_flags)),'h  access_flags:',cf.access_flags);
  swap2(get(@cf.this_class,sizeof(cf.this_class)),0);
  writeln(hex4(rc-sizeof(cf.this_class)),  'h  this_class:  ',cf.this_class);
  swap2(get(@cf.super_class,sizeof(cf.super_class)),0);
  writeln(hex4(rc-sizeof(cf.super_class)), 'h  super_class: ',cf.super_class);
  writeln;
  swap2(get(@cf.interfaces_count,sizeof(cf.interfaces_count)),0);
  writeln(hex4(rc-sizeof(cf.interfaces_count)),'h  INTERFACES_INFO [',cf.interfaces_count,']=');
  p := @cf.interfaces^;
  for i := 0 to cf.interfaces_count-1 do
  begin
    writeln(hex4(rc), 'h  interfaces_info :',i,'___');
    load_interfaces;
  end;
  writeln;
  swap2(get(@cf.fields_count,sizeof(cf.fields_count) ),0);
  writeln(hex4(rc-sizeof(cf.fields_count)),'h  FIELD_INFO [',cf.fields_count,']=');
  p := @cf.field_info^;
  for i := 0 to cf.fields_count-1 do
  begin
    writeln(hex4(rc), 'h  field_info :',i,'___');
    load_field_info;
  end;
  writeln;
  swap2(get(@cf.methods_count,sizeof(cf.methods_count)),0);
  writeln(hex4(rc-sizeof(cf.methods_count)), 'h  METHOD_INFO [',cf.methods_count,']=');
  p := @cf.method_info^;
  for i := 0 to cf.methods_count-1 do
  begin
    writeln(hex4(rc),'h  method_info :',i,'___');
    method_info;
  end;
  writeln;
  swap2(get(@cf.attributes_count,sizeof(cf.attributes_count)),0);
  writeln(hex4(rc-sizeof(cf.attributes_count)),'h  ATTRIBUTE_INFO [',cf.attributes_count,']=');
  p := @cf.attribute_info^;
  for i := 0 to cf.attributes_count-1 do
  begin
    writeln(hex4(rc),'h  attributes_info :',i,'___');
    load_attribute_info;
  end;
  close(f);
  freeMem(cf.attribute_info,  $FFFF);
  freeMem(cf.method_info,     $FFFF);
  freeMem(cf.field_info,      $FFFF);
  freeMem(cf.interfaces,      $7FFF);
  freeMem(cf.cp_info,         $FFFF);
end.
(Offline)
 
Ответить с цитированием
Старый 29.09.2008, 08:21   #56
satan
Нуждающийся
 
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений
(для 28 пользователей)
Re: создание MIDletPascal compiler'a

Гут... Мысль понял... Токма у меня опять в штопор входит...
Надо так, ваще вечером загружу TurboDelphi 2006, оно бесплатное и там помойму с памятью корректнее работает, паетому на ней программы можно и продовать и раздавать... Да и синхронность будет!

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

Теперь пример уже синтаксического анализатора, который разбирает строки вида
N +/- ... Где N - цифра, тоесть типа
1+2-3+1-6 или 3+3+5+6-4 ну и т.д... Начнем с азов...

{$APPTYPE CONSOLE}

const TAB = ^I;
var Look: char;

procedure GetChar; begin Read(Look); end;
procedure Error(s: string); begin WriteLn; WriteLn(^G, 'Error: ', s, '.'); end;
procedure Abort(s: string); begin Error(s); Halt; end;
procedure Expected(s: string); begin Abort(s + ' Expected'); end;
procedure Match(x: char); begin if Look = x then GetChar else Expected('''' + x + ''''); end;
function IsAlpha(c: char): boolean; begin IsAlpha := upcase(c) in ['A'..'Z']; end;
function IsDigit(c: char): boolean; begin IsDigit := c in ['0'..'9']; end;

function GetName: char;
begin
   if not IsAlpha(Look) then Expected('Name');
   GetName := UpCase(Look);
   GetChar;
end;

function GetNum: char;
begin
   if not IsDigit(Look) then Expected('Integer');
   GetNum := Look;
   GetChar;
end;

procedure Emit(s: string); begin Write(TAB, s); end;
procedure EmitLn(s: string); begin Emit(s); WriteLn; end;

//--------------------------S analizator-----------------------------

procedure Term;
begin
   EmitLn('bipush ' + GetNum);
end;

procedure Add;
begin
   Match('+');
   Term;
   EmitLn('iadd');
end;

procedure Sub;
begin
   Match('-');
   Term;
   EmitLn('isub');
   EmitLn('ineg');
end;

procedure Expression;
begin
   Term;
   while Look in ['+', '-'] do begin
      case Look of
       '+': Add;
       '-': Sub;
      else Expected('Addop');
      end;
   end;
end;

//------------------------------------------------------------------

procedure Init;
begin
   GetChar;
end;

begin
   Init;
   Expression;
end.
вобчем сам анализатор пока из 4 фукций

procedure Term;
procedure Add;
procedure Sub;
procedure Expression;

И выдает асм листинг формата JVM
вот пример разбора строки 1+2-3+4-5+6
        bipush 1
        bipush 2
        iadd
        bipush 3
        isub
        ineg
        bipush 4
        iadd
        bipush 5
        isub
        ineg
        bipush 6
        iadd
В принципе немного отличаецо от Java классики, но ето от того что там используетца польская запись, кстати хто заинтересуеца АЛГОРИТМ ДЕКСТРА для перевода текстовой строки в обратную польскую запись.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
abcdef (03.10.2008)
Старый 29.09.2008, 11:12   #57
satan
Нуждающийся
 
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений
(для 28 пользователей)
Re: создание MIDletPascal compiler'a

abcdef ну нифига у тя буйсво мысли... Гы... нафиг такие замуты, Java asm не работает напрямую с переменными, оно работает с адресами и стеком.
Смори, я разбил на диапазоны 1б операции 2б операции и т.д. а все чо не входит естественно без операнда сразу со стеком работает... Паетому немного у тя надо ldc оператор поправить, для него операнд следучий байт, тоесть он однобайтный оператор...
А во смори как из ассемблера токда у меня будет переводица в байт код.
Если ща берём байт код и по нему возвращаем оператор
Прим:
ldc - код 18 или байткод $12 то встретив в коде этот байт мы просто возвращаем его оператор
ByteCode[$12] = ldc
а кокда мы будем конвертить из ассемблера, то так же будем вычислять опкод, токма поиском в массиве по значению "ldc" который нам вернет $12 - номер в массиве, ну тоесть уже готовый асм - дизасм есть...
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
abcdef (03.10.2008)
Старый 29.09.2008, 19:49   #58
abcdef
Знающий
 
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений
(для 123 пользователей)
Ответ: создание MIDletPascal compiler'a

все нормуль! мой массив не просто так делался, будем использовать его в компиляторе, он нужен для проверки параметров команды, и.д., а так прийдется большой case писать...
а здесь задал условия в массиве, и все...


ввиду складывающихся сложных взаимосвязей между объектами
предлагаю разделить Pascal-копилятор на две независимые части:
одна из них генерирует текстовый файл с byte-code листингом,
другая собирает class-файл на основе полученного файла.

1. это позволить упростить компилятор, сделает его менее привязанным к структуре формирования java byte-code и внутреннего представления class-файлов.
2. стадия сборки будет построенна более оптимально и наглядно
3. в промежутке между стадиями компиляции можно ознакомиться, или вручную подредактировать байт-код
(Offline)
 
Ответить с цитированием
Старый 29.09.2008, 20:39   #59
satan
Нуждающийся
 
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений
(для 28 пользователей)
Re: создание MIDletPascal compiler'a

А ну да... Гы...

А если разбивать, потом не возникнет путанки со всякими там USES???
Кстать, кокда буим парсить, так и так все залетит в таблицы (типа переменных, классов, функций и т.д..) иль ты чо придумал хитрае?

Последний раз редактировалось satan, 29.09.2008 в 21:11.
(Offline)
 
Ответить с цитированием
Старый 29.09.2008, 23:18   #60
abcdef
Знающий
 
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений
(для 123 пользователей)
Ответ: создание MIDletPascal compiler'a

вообщем может кому-нить пригодится можно былобы сделать так:
type jcode=record s:array[0..15] of char; count:byte; end;
....
for p:=0 to length-1 do
begin write(jbc[...p...].s); p:=get(p,jbc[...p...].count); если нужно выводим байты end;

мы потратим в структуре 256 байт, но примерно столько съели бы команды разбора и т.д.

предположительная структура асм листинга такова:
константы
команды_java параметы(ссылка на константу/переменную/число)
подпрограмма (параметры) (код)
одна команда на строку

думаю USES будет только для блока массива констант
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Скачать MidletPascal smesh Прочие вопросы 14 30.06.2011 15:57
создание MIDletPascal obfuscator abcdef Основной форум 7 22.12.2008 23:27
Русификатор MIDletPascal Тренсфер Прочие вопросы 14 26.07.2008 04:00
MidletPascal. Что это. Данил MidletPascal 12 23.10.2007 05:27


Часовой пояс GMT +4, время: 15:52.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com