Форум программистов, компьютерный форум, киберфорум
Наши страницы
Lua
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/10: Рейтинг темы: голосов - 10, средняя оценка - 4.60
InfoEL
39 / 2 / 0
Регистрация: 10.05.2012
Сообщений: 68
#1

Написать switch для lua, немного модифицировав исходники интерпретатора

23.07.2014, 17:17. Просмотров 1731. Ответов 6
Метки нет (Все метки)

Привет всем. Уверена, что найдутся люди, которые смогут помочь...
Дело в том, что я решила написать switch для lua, немного модифицировав исходники интерпретатора...

Но довольно сложно ориентироваться в чужом коде, особенно когда его много. Буду рада, если найдутся те, кто не откажется помочь разобраться до конца... (остановилась на функции ifstate() модуля lparser.c)

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.07.2014, 17:17
Ответы с готовыми решениями:

Программа для Lua
Посоветуйте пожалуйста программу для написания, просмотра и отладки lua...

Написать командный сценарий для интерпретатора bash для смены расширения у файлов текущего каталога
Написать командный сценарий для интерпретатора bash для смены расширения у...

Написать бенчмарк для процессора, используя чьи-нибудь исходники в качестве примера
Препод дал задание(для особо умного ученика ) написать бренчмрк для процессора...

Литература для создания элементарного языка управляющих сигналов и интерпретатора для него
Доброго времени суток! Подскажите, с чего начать при создании? Нужно придумать...

Как в visual studio 15 написать самый простой код на LUA
Хочу написать самый простой код на LUA в VS. Для этого взял готовый пример из...

6
BozKurt
297 / 274 / 101
Регистрация: 06.05.2014
Сообщений: 861
Завершенные тесты: 1
28.07.2014, 17:41 #2
Во-первых, вопрос не по Lua.
Во-вторых, зачем? Вот такая конструкция работает не чуть не хуже, а то и лучше:
Javascript
1
2
3
4
5
6
7
8
9
local tbl = {
    [1] = function() print("If value1.") end,
    [2] = function() print("If value2.") end,
    [3] = function() print("If value3.") end,
}
 
local value = 3
 
tbl[value]()
0
InfoEL
39 / 2 / 0
Регистрация: 10.05.2012
Сообщений: 68
29.07.2014, 06:54  [ТС] #3
Да, возможно, ошиблась с темой.
А второе, просто у нас было несколько заданий на выбор. и я выбрала это.. но возникли некоторые сложности.
0
Vtulhu
423 / 377 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
07.11.2014, 12:42 #4
Lua - это гомоиконный язык, как и Lisp. Это означает, что эти языки можно модифицировать средствами самого языка. У них даже неофициальные девизы похожи:
Lisp - программируемый язык программирования.
Lua - расширяемый язык расширений.
1
InfoEL
39 / 2 / 0
Регистрация: 10.05.2012
Сообщений: 68
07.11.2014, 12:46  [ТС] #5
Я уже и забыла про то, что у меня эта тема есть. В общем я все написала и все ок. Тему можно считать закрытой.
0
Avazart
Эксперт С++
7696 / 5605 / 543
Регистрация: 10.12.2010
Сообщений: 25,167
Записей в блоге: 17
07.11.2014, 15:35 #6
InfoEL, Решение приведите, наверняка кому-то еще пригодится.
2
InfoEL
39 / 2 / 0
Регистрация: 10.05.2012
Сообщений: 68
08.11.2014, 01:20  [ТС] #7
Во-первых, необходимо зарезервировать сл. слова(switch, case в зависимости от синтаксиса, который вы хотите реализовать).
Сразу говорю..Что я писала под сл. синтаксис
C
1
2
3
4
5
6
switch ((k + 1) * 2) / 2 begin
  case 1 then print("val = 1"); print("WA");
  case 2 then print("val = 2"); print("WA");
  case 3 then print("val = 3"); print("OK");
  default print("default value"); print("WA");
end;
Далее, находим массив в модуле llex.c и добавляем новые слова, слова нашего оператора(Либо сразу после "while", либо до него, позже станет ясно почему).
C
1
2
3
4
5
6
7
8
9
10
static const char *const luaX_tokens [] = {
    "and", "break", "do", "else", "elseif",
    "end", "false", "for", "function", "goto", "if",
    "in", "local", "nil", "not", "or", "repeat",
    "return", "then", "true", "until", "while",
    /* my switch reserved words */
    "switch", "case", "default", "begin",
    "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
    "<number>", "<name>", "<string>",
};
В заголовочном файле llex.h найдем и добавим слова в перечислении, т. н. токены
C
1
2
3
4
5
6
7
8
9
10
11
12
enum RESERVED {
  /* terminal symbols denoted by reserved words */
  TK_AND = FIRST_RESERVED, TK_BREAK,
  TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
  TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
  TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
  /* switch statement */
  TK_SWITCH, TK_CASE, TK_DEFAULT, TK_BEGIN,
  /* other terminal symbols */
  TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS,
  TK_NUMBER, TK_NAME, TK_STRING,
};
Порядок должен соблюдаться, ну понятно почему, надеюсь.

Если вы добавляли новые слова и токены сразу после "while" и TK_WHILE, то необходимо обратить внимание на
C
1
2
/* number of reserved words */
#define NUM_RESERVED    (cast(int, TK_WHILE-FIRST_RESERVED+1))
и заменить, в моем случае на
C
1
2
/* number of reserved words */
#define NUM_RESERVED    (cast(int, TK_BEGIN-FIRST_RESERVED+1))
то есть это кол-во ключевых слов.

Далее, модуль lparser.c(в котором у меня и возникли сложности, из-за чего я и отписалась на форуме)
Находим функцию statement(); И вы видите там большой case на каждый оператор.
добавим еще один случай, который будет срабатывать, если встретится слово switch в нашем lua-скрипте
C
1
2
3
4
case TK_SWITCH:{
      switchstat(ls, line);
      break;
    }
Выше, пишем функцию switchstat(). Я писала по аналогии с оператором if...Поэтому можете прямо возле него и писать свой код, дабы видеть разницу и сходства.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static void switchstat (LexState *ls, int line) {
  /* switchstat -> SWITCH control CASE value THEN block [DEFAULT block] END */
  FuncState *fs = ls->fs;
  int escapelist = NO_JUMP; /* exit list for finished parts */
  expdesc control;
  luaX_next(ls); /* skip SWITCH */
  expr(ls, &control); /* read control */
  check(ls, TK_CASE);
  while (ls->t.token == TK_CASE)
    test_case_block(ls, &escapelist, &control); /* CASE value THEN block */
  if (testnext(ls, TK_DEFAULT))
    block(ls); /* DEFAULT block */
  check_match(ls, TK_END, TK_SWITCH, line);
  luaK_patchtohere(fs, escapelist);
}
Также необходимо написать еще одну функцию - test_case_block, которая будет вызываться только в switchstat()
(По аналогии test_then_block в ifstat());
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
static void test_case_block (LexState *ls, int *escapelist, expdesc *control) {
  /* test_case_block -> CASE value THEN block */
  BlockCnt bl;
  FuncState *fs = ls->fs;
  expdesc v;
  int jf; /* instruction to skip 'then' code (if condition is false) */
 
  luaX_next(ls); /* skip CASE */
  expr(ls, &v); /* read condition */
  luaK_posfix(fs, OPR_EQ, control, &v, ls->linenumber);
  checknext(ls, TK_THEN);
 
  if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
    luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
    enterblock(fs, &bl, 0); /* must enter block before 'goto' */
    gotostat(ls, v.t); /* handle goto/break */
    skipnoopstat(ls); /* skip other no-op statements */
    if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
      leaveblock(fs);
      return; /* and that is it */
    } 
    else /* must skip over 'then' part if condition is false */
      jf = luaK_jump(fs);
  }
  else { /* regular case (not goto/break) */
    luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */
    enterblock(fs, &bl, 0);
    jf = v.f;
  }
  statlist(ls); /* `then' part */
  leaveblock(fs);
 
  if (ls->t.token == TK_DEFAULT || ls->t.token == TK_CASE) /* followed by 'default'/'case'? */
    luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */
  luaK_patchtohere(fs, jf);
}
Вот. теперь у нас при встрече ключевого слова "switch" будет вызываться наша новая функция switchstat.
Это не все.
Eще выше найдем функцию
C
1
2
3
4
5
6
7
8
9
10
static int block_follow (LexState *ls, int withuntil) {
  switch (ls->t.token) {
    case TK_ELSE: case TK_ELSEIF:
    case TK_CASE: case TK_DEFAULT: 
    case TK_END: case TK_EOS:
      return 1;
    case TK_UNTIL: return withuntil;
    default: return 0;
  }
}
и добавляем TK_END, TK_DEFALT там, где возвращается 1. Эта функция возвращает 1, если встретила новый, следующий блок..
Ну вроде все, написала. Теперь собираем наш интерпретатор и проверяем. По-хорошему, нужно хорошо протестировать, правильно ли везде работает. Я проверяла, что-то поисправляла, проверок добавила. Если будут какие замечания. пишете, предлагайте свои решения.

Добавлено через 2 минуты
Забыла указать, что работала с исходниками lua-5.2.0
1
08.11.2014, 01:20
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.11.2014, 01:20

Командный сценарий для интерпретатора bash
Ребят, нужна помощь по лабе. 1.Написать командный сценарий для...

Составить вывод интерпретатора для формулы
Помогите составить вывод интерпретатора для формулы 42/4+2*(-2)

Командный сценарий для интерпретатора bash
Всем привет. Нужна помощь. Написать командный сценарий для интерпретатора...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru