Я разрабатываю свой собственный экспериментальный язык сценариев с целью его внедрения в моем более крупном приложении.Структура данных для хранения переменных в интерпретируемом языке
Почти все, что я хотел сделать, было запрограммировано плавно, но «простой» акт хранения переменных в памяти оказался здесь самым сложным. Я не знаю, как их хранить, чтобы разрешить все проверки типов, глобальные переменные и специальные флаги. Первый взгляд на примере кода:
a = 1
b = 2
someFunction()
print(a) --> This should read the global variable and print `1`
a = 3 --> Now `a` should become a local variable of this function
and the global `a` remain unchanged
x = 4 --> `x` should always be local of this function
end
я называю «локальность» переменных их level
ы так переменных во вложенных блоках, имеют более высокий уровень. В приведенном выше коде a
и b
являются переменными уровня 1. Локальные переменные someFunction будут иметь уровень 2. Первая строка функции должна читать глобальную переменную a
(уровень 1), но вторая строка должна создать переменную, которая снова называется a
, но с уровнем 2, который с этого момента сбрасывает глобальный a
. Третья строка должна создать переменную x
с уровнем 2. Как хранить и отслеживать все это в памяти?
То, что я пытался до сих пор:
Метод 1: Сохранение карт variable=>value
в массиве уровней:
variables
{
level=1 //global variables
{
a => 1,
b => 2
},
level=2 //function variables
{
a => 3,
x => 4
}
}
Но это будет сделать переменную просмотровых очень медленно, так как приходится искать все уровни для данной переменной.
Метод 2: Сохранение (Variable, уровень) пар в качестве ключей карты:
variables
{
(a, 1) => 1, //global
(b, 1) => 2, //global
(a, 2) => 3, //function
(x, 2) => 3 //function
}
Это та же проблема, как и раньше, так как мы должны попробовать пару (переменная, уровень) со всеми возможными уровней для данной переменной.
Какой метод следует использовать для оптимального использования памяти и быстрого доступа?
Дополнительные примечания:
Я знаю о том, как переменные управляются в стеке и куче на других «настоящих» языков, но я считаю, это сложно сделать это на интерпретируемых языках. «Это не должно быть так, как это делают Луа и Питон», - я всегда думаю. Поправьте меня если я ошибаюсь. Я пытаюсь сохранить переменную в картах и внутренних структурах C++.
И, наконец, я представляю переменную. Считаете ли вы, что он большой, и могут быть более эффективные с точки зрения памяти представления? (Я также попытался поставить «Level» в качестве члена здесь, но это была та же проблема, как и другие тоже.)
struct Member
{
uchar type; //0=num, 1=str, 2=function, 3=array, etc
uchar flags; //0x80 = read-only, 0x40 = write-only, etc
union {
long double value_num;
char* value_str;
int value_func;
//etc
};
};
Я бы использовал карту, которая отображает каждое имя переменной в стек экземпляров переменной. Когда вы создаете новую переменную на уровне, переменная в стеке, а самый верхний элемент в стеке содержит текущий видимый экземпляр переменной с этим именем. Также вам необходимо поддерживать список выделенных переменных для каждого уровня, чтобы вытеснять переменные из стека при выходе из уровня. смысл, я никогда не разрабатывал сам язык. – Nobody
Вы можете просто использовать стек массивов и некоторую форму индексов de Bruijn. Выполните примитивный «compi перед тем, как интерпретировать, разрешив все имена. –