Форум программистов, компьютерный форум CyberForum.ru

Пишем свой интерпретатор языка BASIC - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 1509, средняя оценка - 4.80
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
20.06.2009, 20:03     Пишем свой интерпретатор языка BASIC #1
*****************
Благодаря форуму и Evg в частности интерпретатор развивается, потихоньку превращаясь в простенький интерпретатор QBASIC.
Некоторые из самых старых версий сохранились в теме и ссылки на них будут добавлены в это сообщение,а также ссылки на другие темы,связанные с этой.

Репозиторий с проектом находится тут, там же есть возможность в браузере посмотреть историю ревизий (английский в логах весьма примитивен,комментарии и рекомендации можете писать в личку),а также скачать самый последний архив репозитория в формате .tar.gz
Если кто-то пользуется Subversion,скачать исходники можно так:
Код
svn co https://basin.svn.sourceforge.net/svnroot/basin basin
Эти темы возникли в результате моих вопросов по ходу написания:
Технический приём для формирования согласованных данных
Makefile: как с использованием gcc строить автоматические зависимости от .h файлов?
Вопрос по svn (Subversion)
Создание системы тестирования ПО.
Вопрос про разные реализации бэйсиков
[C/C++] Можно ли выразить порядковый номер элемента массива через индексы?
[C++] Какие флаги указать линкеру для компиляции программы?
Как можно определить переменную в файле configure.in,чтобы её можно было использовать в Makefile?
Странный SIGSEGV, или что зависит от порядка написания интерфейса класса
[C++]Можно ли как-то указать в Makefile,чтобы часть файлов компилировал компилятор C?
Альтернативная версия интерпретатора от Evg на C
Это простая реализация разбора выражений, написанная Evg на C:
Представление выражения в двоичном дереве
*****************
Первое сообщение:
*****************
Задание(Страуструп,из книги,по готовому коду): Введите программу калькулятора и заставьте её работать.Например,при вводе
C++
1
2
r = 2.5
area = pi*r*r
Программа калькулятора выведет:
C++
1
2
2.5
19.635
Получили такой код:
LexicalAnalyzer.h
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
// LexicalAnalyzer.h
#ifndef LEXICALANALYZER_H_INCLUDED
#define LEXICALANALYZER_H_INCLUDED
 
#include <cctype>
#include <string>
#include <map>
#include <iostream>
 
enum Token_value {
    NAME,       NUMBER,      END,
    PLUS = '+', MINUS = '-', MUL = '*', DIV = '/',
    PRINT = ';',ASSIGN = '=',LP = '(',  RP = ')'
};
extern Token_value curr_tok;
extern std::map<std::string,double>table;
extern int no_of_errors;
 
Token_value get_token();
 
double expr(bool);
double term (bool);
double prim (bool);
int error(const std::string&);
 
#endif // LEXICALANALYZER_H_INCLUDED

LexicalAnalyzer.cpp
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// LexicalAnalyzer.cpp
#include "LexicalAnalyzer.h"
 
 
std::map<std::string,double>table;
Token_value curr_tok=PRINT;
 
double expr (bool get)
{
    double left = term(get);
 
    for (;;)
        switch (curr_tok) {
            case PLUS:
                 left += term(true);
            break;
            case MINUS:
                 left-= term(true);
            break;
            default:
                 return left;
        }
}
 
double term (bool get)
{
    double left = prim (get);
 
    for (;;)
        switch (curr_tok) {
            case MUL:
                 left*=prim(true);
            break;
            case DIV:
                 if (double d = prim (true)) {
                     left /= prim (true);
                     break;
                 }
                 return error("Деление на ноль");
            default:
                 return left;
        }
}
 
double number_value;
std::string string_value;
 
double prim (bool get)
{
    if (get) get_token();
    switch (curr_tok){
        case NUMBER:{
            double& v = number_value;
            get_token();
            return v;
        }
        case NAME:{
            double& v = table[string_value];
            if (get_token()==ASSIGN) v = expr(true);
            return v;
        }
        case MINUS:
            return -prim(true);
        case LP:{
            double e = expr(true);
            if (curr_tok!=RP) return error("Ожидалась )");
            get_token();
            return e;
        }
        default:
            return error("Ожидалось первичное выражение");
    }
}
 
Token_value get_token()
{
    char ch = 0;
 
    do {
        if (!std::cin.get(ch)) return curr_tok = END;
    } while (ch!='\n'&&isspace(ch));
 
    switch (ch) {
        case 0:
             return curr_tok = END;
        case ';':case '\n':
             return curr_tok = PRINT;
        case '*':case'/':case '+':case '-':case '(':case ')':case '=':
             return Token_value(ch);
        case '0':case '1':case '2':case '3':case '4' :
        case '5':case '6':case '7':case '8':case '9':case '.':
             std::cin.putback(ch);
             std::cin>>number_value;
             return curr_tok=NUMBER;
        default:
             if (isalpha(ch)) {
                 string_value = ch;
                 while (std::cin.get(ch)&&isalnum(ch)) string_value.push_back(ch);
                 std::cin.putback(ch);
                 return curr_tok = NAME;
             }
             error ("Неправильная лексема");
             return curr_tok = PRINT;
    }
}
int no_of_errors=0;
int error (const std::string& s)
{
    no_of_errors++;
    std::cerr<<"Ошибка: "<<s<<'\n';
    return no_of_errors;
}

main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// main.cpp
#include "LexicalAnalyzer.h"
 
 
int main()
{
    table["pi"]=3.1415926535897932385;
    table["e"]=2.7182818284590452354;
    while (std::cin) {
        get_token();
        if (curr_tok==END) break;
        if (curr_tok==PRINT) continue;
        std::cout<<expr(false)<<'\n';
    }
    return no_of_errors;
}

Анализатор-то работает,но конечное значение не вычисляется.Более того,если вводим
C++
1
a = 3 + 6
,то получаем "a", равное первому элементу в выражении,то есть 3.В чём логическая ошибка данной программы?С этими каскадными вызовами она слегка запутана.Уверен,что кто-то уже делал это задание.

Добавлено через 2 часа 5 минут 30 секунд
Пришлось решать влоб с дебаггером.У Страуструпа опечатка (или намеренная ошибка,что более вероятно ) Вот в этом куске кода в функции get_token():
C++
1
2
        case '*':case'/':case '+':case '-':case '(':case ')':case '=':
             return Token_value(ch);
Нехватает смены значения curr_tok,что и приводит к ошибочной работе.
C++
1
2
        case '*':case'/':case '+':case '-':case '(':case ')':case '=':
             return curr_tok=Token_value(ch);
Теперь всё пашет,всем спасибо,вопрос можно считать закрытым,но есть вопрос поважнее: В функциях prim и term возвращается int при ошибке,но ведь они имеют тип double,как вообще это работает?Происходит неявное преобразование типа,так?Мне интересно,почему Страуструп прибег к такому способу,это распространённая практика?

Добавлено через 16 минут 19 секунд
И ещё опечатка была
C++
1
2
3
                 if (double d = prim (true)) {
                     left /= d;// было left /= prim (true)
                     break;
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
HIMen
 Аватар для HIMen
4104 / 1353 / 39
Регистрация: 12.04.2009
Сообщений: 2,346
11.06.2010, 00:19     Пишем свой интерпретатор языка BASIC #381
Вот что у меня получилось:
3 типа переменных: int, string, bool, все глобальные, для них определены основные операции с приоритетами, кроме унарного минуса
Ветвление if - else
Цикл while, break
Ветвления и циклы могут быть вложенными.
В IDE пока работает только одна кнопка - запуск

C#, Framework 2.0, кому интересен код - пишите в личку
Вложения
Тип файла: rar int.rar (27.3 Кб, 61 просмотров)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Egeni
10 / 10 / 1
Регистрация: 17.06.2010
Сообщений: 107
Записей в блоге: 1
22.06.2010, 20:25     Пишем свой интерпретатор языка BASIC #382
а ты не пробовал собрать это на билдере помойму быстрее будет работать...
HIMen
 Аватар для HIMen
4104 / 1353 / 39
Регистрация: 12.04.2009
Сообщений: 2,346
22.06.2010, 20:53     Пишем свой интерпретатор языка BASIC #383
Egeni, Возможно, но я сейчас пробую делать трансляцию в IL, получится .NET совместимый язык и по скорости не будет уступать остальным компилируемым языкам
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
09.08.2010, 23:06  [ТС]     Пишем свой интерпретатор языка BASIC #384
Evg ,у меня есть вопрос по теории. Допустим,мне удалось сделать вызов функций с помощью меток перехода,что не вызывает рекурсии в интерпретаторе.

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

Не мог бы ты немного прояснить этот момент? Так ли это плохо,рекурсия в интерпретирующей программе,и если да,то как можно этого избежать? Я примерно представляю себе,что нужно строить ещё некое подобие "очереди выражений",или промежуточные вычисления для выражений,наподобие регистров,чтобы избежать рекурсии.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
10.08.2010, 00:16     Пишем свой интерпретатор языка BASIC #385
Если у тебя рекурсия в выражении, то рекурсия в интерпретаторе - это нормальное явление. Но при этом вложенность вызовов в интерпретаторе условно должна быть такой же, как и в исходнике. Операция вызова всегда обладает стековой структурой, потому что как минимум должна сохраняться точка возврата. В твоём случае ещё и должен сохраняться контекст (значение локальных переменных в точке вызова). И эти стеки будут расти параллельно со стеком исполнения (т.е. с процессом рекурсии внутри интерпретатора)
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
24.10.2010, 23:19  [ТС]     Пишем свой интерпретатор языка BASIC #386
Заработал некий кастрированный вариант SUB с рекурсией, начиная с версии 0.84 .До переполнения стека я не дождался,как-нибудь попробую,к тому же,там через метки перехода сделано,а все данные в динамической памяти,так что,наверное,долго ждать нужно. Для теста можно использовать исходник ниже (или запустить главный исходник из каталога tests - /tests/sources/source.bas):

QBASIC source
PureBasic
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
  LET b$ = "bbb"
  PRINT "Original b$ before function call: ",b$:PRINT
  
  DIM SHARED count AS INTEGER
  LET count = 0
 
   '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
   SUB myfunc 
   
      PRINT
      
      LET b$ = "Let there be recursion."
      PRINT "b$ inside function call: ", b$:PRINT
      
      PRINT
      LET count = count + 1
      IF count < 10 THEN
       CALL myfunc
      END IF 
      
   END SUB
   '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
   CALL myfunc
   '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
   PRINT "b$ after funtion call: ",b$:PRINT


Конечно,данный вариант рекурсии имеет мало смысла, но по крайней мере,механизм рекурсии сам по себе вроде работает.
Если кто найдёт баги,ломающие интерпретатор (с помощью QBASIC-исходника имеется ввиду) - пишите.
Осталось добавить работу с параметрами,и FUNCTION,возвращающую значение.
Теперь потихоньку разгебу бардак с памятью (мне опять нетерпелось сделать поскорее,чтобы увидеть результат рекурсии). Фуккции,конечно,внесли много запутанности в логику работы,в логику кода вообще,так как изначально было не понятно,как всё это реализовывать.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
24.10.2010, 23:50     Пишем свой интерпретатор языка BASIC #387
А как в бэйсике область видимости определяется? Если в Си ещё понятно (там есть глобалы и локалы), то здесь я чего-то так и не понял... Что означает SHARED?
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
25.10.2010, 00:00  [ТС]     Пишем свой интерпретатор языка BASIC #388
Как я понял,все переменные в QBASIC - локальные внутри области видимости функции. Глобальная область видимости (имеется само тело прорграммы,не функции) перекрывается функциями. Если нужен доступ к переменной по всей программе,включая внутри функций,при объявлении этой переменной добавляется слово SHARED. Работает (вроде) только вкупе с DIM

Не по теме:

http://en.wikibooks.org/wiki/QBasic/Full_Book_View#Declaring_a_subroutine


Блин,я что не так понял,что-ли? Сейчас перечитываю,там вроде как написано,что в теле функции надо их объявлять,эти shared-переменные... Не помню,где такое ранее прочитать мог,но вроде проверял на настоящем бэйсике,вроде как сделал-правильно

А-a,вот где я прочитал про SHARED!

Не по теме:

http://www.qbasicstation.com/index.php?c=t_adv&t=13

Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
25.10.2010, 00:18     Пишем свой интерпретатор языка BASIC #389
Ты всё-таки напиши, как это реализовано у тебя. Те, кто разбирается в бэйсике, в случае чего укажут на неправильные места. Те, кто в бэйсике не специалист, хотя бы поймут как интерпретатор тестировать (т.е. чего ожидать от программы)
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
25.10.2010, 00:24  [ТС]     Пишем свой интерпретатор языка BASIC #390
В-общем,есть главный контейнер с данными(свой для массивов и свой для переменных),эти переменные видимы по всей программе,за исключением случаев вызова функций,когда интерпретируется тело функции. В этом случае,если в теле функции встречается переменная с тем же именем,что и в главном листе,конфликта деклараций не происходит,а просто создаётся переменная в собственном контейнере для этой функции.
Если же какую-либо переменную объявить через
PureBasic
1
DIM SHARED [var] [AS] [TYPENAME]
то тогда эта переменная будет видима из всех функций и по всей программе,и тогда нельзя будет объявить ещё одну такую же переменную где бы то ни было,и она будет глобальной,её значение будет меняться из любого участка программы.
Кстати,у меня есть баг с поиском переменных по листам/контейнерам,а я и забыл... там какие-то взаимоисключающие логические условия(алгоритм довольно неудачный),это надо копаться будет ещё
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
25.10.2010, 15:28     Пишем свой интерпретатор языка BASIC #391
Цитата Сообщение от #pragma Посмотреть сообщение
и тогда нельзя будет объявить ещё одну такую же переменную где бы то ни было
Это что, в бэйсике так придумано? С виду выглядит через ж...у, но логика вроде бы такая, что переменная с модификатором SHARED - это в чистом виде глобал, а без модификатора - локал. При этом возникает понятие локальной переменной для всего модуля, но вроже бы как ничему не противоречит. Кроме, возможно, случая, когда исходник состоит из нескольких файлов, но я не уверен, что такое хозяйство у кого-то работает на интерпретаторах, скорее всего такое только в компиляторах

Добавлено через 9 минут
На всякий случай лог сборки компилятором g++-4.1.2 - много warning'ов.
У меня qt или нет или кривая версия, а потому оно не собралось. Систему configure надо бы научить это дело понимать, выдавать предупреждение, что у вас не будет GUI и не запускать его сборку

Сборка компилятором g++-4.1.2
$ make
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/debug/error_handler.cpp -o Interpreter/debug/error_handler.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/main.cpp -o Interpreter/main.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/lib/lib.cpp -o Interpreter/lib/lib.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/cmd/options.cpp -o Interpreter/cmd/options.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/memory/memory.cpp -o Interpreter/memory/memory.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/frontend/parser.cpp -o Interpreter/frontend/parser.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/frontend/syntax.cpp -o Interpreter/frontend/syntax.o
Interpreter/frontend/syntax.cpp: In function 'expr_Node_t* syntax_Procedure(var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:481: warning: 'params' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'expr_Node_t* syntax_Primary(var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:346: warning: 'zero' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:359: warning: 'ind' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:373: warning: 'ind' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:145: warning: 'expr' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtDIM(var_Arr_t*, arr_Arr_t*)':
Interpreter/frontend/syntax.cpp:1183: warning: 'arr_elem_type' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1128: warning: 'start_indexes' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1127: warning: 'indexes' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1074: warning: 'var_type' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtCLEAR(stmt_List_t*)':
Interpreter/frontend/syntax.cpp:1514: warning: 'parameters' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1515: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtBEEP(stmt_List_t*)':
Interpreter/frontend/syntax.cpp:1507: warning: 'parameters' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1508: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtEND(stmt_List_t*)':
Interpreter/frontend/syntax.cpp:1501: warning: 'parameters' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1502: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtCLS(stmt_List_t*)':
Interpreter/frontend/syntax.cpp:1494: warning: 'parameters' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1495: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtCIRCLE(stmt_List_t*, var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:1469: warning: 'parameters' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1488: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtLINE(stmt_List_t*, var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:1411: warning: 'parameters' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1463: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtPRESET(stmt_List_t*, var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:1389: warning: 'parameters' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1405: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtSCREEN(stmt_List_t*, var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:1374: warning: 'parameters' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1383: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtCALL(stmt_List_t*)':
Interpreter/frontend/syntax.cpp:1354: warning: 'name' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1359: warning: 'parameters' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1360: warning: 'function_call' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1363: warning: 'return_from_call' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_Label(stmt_List_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:1032: warning: 'addr' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1038: warning: 'label' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtGOTO(stmt_List_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:1009: warning: 'label' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1016: warning: 'label' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtINPUT(stmt_List_t*, var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:649: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:650: warning: 'var_list' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:417: warning: 'zero' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:446: warning: 'ind' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:432: warning: 'ind' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_stmtPRINT(stmt_List_t*, var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:599: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:602: warning: 'print_expr_list' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:607: warning: 'print_expr_list' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'stmt_Node_t* syntax_stmtLET(stmt_List_t*, var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:515: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:539: warning: 'indexes' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:562: warning: 'indexes' is used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'stmt_Node_t* syntax_stmtFOR(stmt_List_t*, var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:818: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:856: warning: 'cbr_stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:857: warning: 'loop' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:973: warning: 'increment' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:975: warning: 'check' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:977: warning: 'lbl_on_true' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:979: warning: 'lbl_on_false' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:855: warning: 'rel_expr' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'stmt_Node_t* syntax_CBranch(stmt_List_t*, var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/frontend/syntax.cpp:727: warning: 'label_finish' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:751: warning: 'lbl_on_false' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:776: warning: 'label_finish' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:793: warning: 'lbl_on_false' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:802: warning: 'cbr_stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:803: warning: 'loop' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:805: warning: 'check' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:807: warning: 'lbl_on_true' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:809: warning: 'lbl_on_false' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:987: warning: 'loop' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:991: warning: 'cbr_stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:992: warning: 'lbl_on_true' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:994: warning: 'lbl_on_false' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:786: warning: 'label_finish' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:784: warning: 'lbl_on_false' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:783: warning: 'lbl_to_finish' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:770: warning: 'label_finish' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:764: warning: 'lbl_on_false' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:763: warning: 'lbl_to_finish' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:758: warning: 'lbl_on_true' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:739: warning: 'label_finish' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:737: warning: 'lbl_on_false' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:735: warning: 'lbl_to_finish' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:710: warning: 'label_finish' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:703: warning: 'lbl_on_false' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:702: warning: 'lbl_to_finish' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:697: warning: 'lbl_on_true' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:693: warning: 'cbr_stmt' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp: In function 'void syntax_Check()':
Interpreter/frontend/syntax.cpp:1788: warning: 'stmt' is used uninitialized in this function
Interpreter/frontend/syntax.cpp:1314: warning: 'exit_from_call' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1307: warning: 'function_call' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1306: warning: 'parameters' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1338: warning: 'body_end' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1335: warning: 'exit_from' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1280: warning: 'addr' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1268: warning: 'lcl_lbls' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1267: warning: 'lcl_arrs' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1266: warning: 'lcl_vars' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1263: warning: 'arrs_val_stack' may be used uninitialized in this function
Interpreter/frontend/syntax.cpp:1255: warning: 'name' may be used uninitialized in this function
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/intermediate/value.cpp -o Interpreter/intermediate/value.o
Interpreter/intermediate/value.cpp: In member function 'Value Value::operator/(const Value&)':
Interpreter/intermediate/value.cpp:485: warning: passing 'double' for argument 1 to 'void Value::Set_ival(_int_t)'
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/intermediate/variable.cpp -o Interpreter/intermediate/variable.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/intermediate/expression.cpp -o Interpreter/intermediate/expression.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/intermediate/statement.cpp -o Interpreter/intermediate/statement.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/intermediate/array.cpp -o Interpreter/intermediate/array.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/intermediate/label.cpp -o Interpreter/intermediate/label.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/runtime/interp.cpp -o Interpreter/runtime/interp.o
Interpreter/runtime/interp.cpp: In function 'Value interp_CalcExpr(const expr_Node_t*, var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/runtime/interp.cpp:383: warning: 'parameters' is used uninitialized in this function
Interpreter/runtime/interp.cpp: In function 'stmt_Node_t* interp_stmtLET(stmt_Node_t*, var_Arr_t*, arr_Arr_t*, lab_Arr_t*)':
Interpreter/runtime/interp.cpp:466: warning: 'value' is used uninitialized in this function
Interpreter/runtime/interp.cpp:480: warning: 'value' is used uninitialized in this function
Interpreter/runtime/interp.cpp: In function 'void interp_Run()':
Interpreter/runtime/interp.cpp:404: warning: 'parameters' may be used uninitialized in this function
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/runtime/function.cpp -o Interpreter/runtime/function.o
Interpreter/runtime/function.cpp: In function 'Value func_Calculate(const expr_Node_t*, val_Arr_t*)':
Interpreter/runtime/function.cpp:286: warning: 't' may be used uninitialized in this function
Interpreter/runtime/function.cpp:304: warning: 't' may be used uninitialized in this function
Interpreter/runtime/function.cpp:323: warning: 't2' may be used uninitialized in this function
Interpreter/runtime/function.cpp:323: warning: 't1' may be used uninitialized in this function
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/runtime/graphics/graphics.cpp -o Interpreter/runtime/graphics/graphics.o
Interpreter/runtime/graphics/graphics.cpp: In function 'void graphics_PRESET(val_Arr_t*)':
Interpreter/runtime/graphics/graphics.cpp:215: warning: 'color' may be used uninitialized in this function
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/runtime/tracer/tracer.cpp -o Interpreter/runtime/tracer/tracer.o
g++ -c -MD -ansi -pedantic -pedantic-errors -Wall -O2 -Os -I. -IInterpreter/runtime -IInterpreter/runtime/graphics -IInterpreter/runtime/tracer -IInterpreter/cmd -IInterpreter/config -IInterpreter/debug -IInterpreter/frontend -IInterpreter/intermediate -IInterpreter/lib -IInterpreter/include -IInterpreter/memory -IInterpreter Interpreter/runtime/pool.cpp -o Interpreter/runtime/pool.o
Interpreter/runtime/pool.cpp:293:1: warning: "/*" within comment
Interpreter/runtime/pool.cpp: In member function '_bool_t Pool::isConflictingDeclaration(std::string, unsigned int)':
Interpreter/runtime/pool.cpp:208: warning: 'and' of mutually exclusive equal-tests is always 0
Interpreter/runtime/pool.cpp:221: warning: 'and' of mutually exclusive equal-tests is always 0
Interpreter/runtime/pool.cpp:234: warning: 'and' of mutually exclusive equal-tests is always 0
Interpreter/runtime/pool.cpp:247: warning: 'and' of mutually exclusive equal-tests is always 0
g++ -lSDL Interpreter/debug/error_handler.o Interpreter/main.o Interpreter/lib/lib.o Interpreter/cmd/options.o Interpreter/memory/memory.o Interpreter/frontend/parser.o Interpreter/frontend/syntax.o Interpreter/intermediate/value.o Interpreter/intermediate/variable.o Interpreter/intermediate/expression.o Interpreter/intermediate/statement.o Interpreter/intermediate/array.o Interpreter/intermediate/label.o Interpreter/runtime/interp.o Interpreter/runtime/function.o Interpreter/runtime/graphics/graphics.o Interpreter/runtime/tracer/tracer.o Interpreter/runtime/pool.o -o basin \
&& /bin/mv ./basin ./bin/basin
cd ./GUI/Qt/Basin-IDE && /usr/bin/qmake -project \
&& /usr/bin/qmake && /usr/bin/make && cd .. && cd .. && cd .. \
&& /bin/mv ./GUI/Qt/Basin-IDE/Basin-IDE ./bin/Basin-IDE


Сборка GUI
g++ -c -pipe -O2 -march=pentium3 -mtune=pentium4 -pipe -fno-strict-aliasing -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -I. -o editor.o editor.cpp
In file included from editor.cpp:22:
editor.h:22:26: error: QPlainTextEdit: No such file or directory
editor.h:36: error: expected class-name before '{' token
editor.h:36: warning: 'class CodeEditor' has virtual functions but non-virtual destructor
editor.h: In constructor 'LineNumberArea::LineNumberArea(CodeEditor*)':
editor.h:64: error: no matching function for call to 'QWidget::QWidget(CodeEditor*&)'
/usr/include/qt4/QtGui/qwidget.h:728: note: candidates are: QWidget::QWidget(const QWidget&)
/usr/include/qt4/QtGui/qwidget.h:669: note: QWidget::QWidget(QWidgetPrivate&, QWidget*, Qt::WindowFlags)
/usr/include/qt4/QtGui/qwidget.h:219: note: QWidget::QWidget(QWidget*, Qt::WindowFlags)
editor.cpp: In constructor 'CodeEditor::CodeEditor(QWidget*)':
editor.cpp:24: error: class 'CodeEditor' does not have any field named 'QPlainTextEdit'
editor.cpp:29: error: 'connect' was not declared in this scope
editor.cpp:43: error: 'setFont' was not declared in this scope
editor.cpp:44: error: 'setLineWidth' was not declared in this scope
editor.cpp:46: error: 'document' was not declared in this scope
editor.cpp: In member function '_int_t CodeEditor::lineNumberAreaWidth()':
editor.cpp:52: error: 'blockCount' was not declared in this scope
editor.cpp:58: error: 'fontMetrics' was not declared in this scope
editor.cpp: In member function 'void CodeEditor::updateLineNumberAreaWidth(_int_t)':
editor.cpp:65: error: 'setViewportMargins' was not declared in this scope
editor.cpp: In member function 'void CodeEditor::updateLineNumberArea(const QRect&, _int_t)':
editor.cpp:76: error: 'viewport' was not declared in this scope
editor.cpp: In member function 'void CodeEditor::resizeEvent(QResizeEvent*)':
editor.cpp:82: error: 'QPlainTextEdit' has not been declared
editor.cpp:84: error: 'contentsRect' was not declared in this scope
editor.cpp: In member function 'void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent*)':
editor.cpp:94: error: 'firstVisibleBlock' was not declared in this scope
editor.cpp:95: error: 'class QTextBlock' has no member named 'blockNumber'
editor.cpp:97: error: 'blockBoundingGeometry' was not declared in this scope
editor.cpp:97: error: 'contentOffset' was not declared in this scope
editor.cpp:99: error: 'blockBoundingRect' was not declared in this scope
editor.cpp:103: error: 'class QTextBlock' has no member named 'isVisible'
editor.cpp:108: error: 'fontMetrics' was not declared in this scope
editor.cpp: In member function 'void CodeEditor::highlightCurrentLine()':
editor.cpp:125: error: 'textCursor' was not declared in this scope
editor.cpp:129: error: 'setExtraSelections' was not declared in this scope
editor.cpp: In member function 'void CodeEditor::highlightCurrentErrorLine(const QString&)':
editor.cpp:140: error: 'textCursor' was not declared in this scope
editor.cpp:160: error: 'setTextCursor' was not declared in this scope
editor.cpp:161: error: 'setExtraSelections' was not declared in this scope
editor.cpp:162: error: 'ensureCursorVisible' was not declared in this scope
make[1]: *** [editor.o] Error 1


Добавлено через 26 минут
Написал пример:

PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
DIM SHARED glob AS INTEGER
LET glob = 10
 
SUB func1
  LET loc = loc + 1
  PRINT "func1: glob="; glob; "; loc="; loc
  LET glob = glob - 1
  IF glob > 0 THEN
    CALL func2
  END IF 
END SUB
 
SUB func2
  LET loc = loc + 1
  PRINT "func2: glob="; glob; "; loc="; loc
  CALL func1
END SUB
 
CALL func1
 
PRINT "main end: glob="; glob; "; loc="; loc
Интерпретатор не захотел понимать вызов функции до того, как она будет объявлена

Код
file: a.bas line: 9 error: Undefined function: FUNC2
После чего "CALL func2" заменил на "CALL func1" (чтобы обойтись рекурсией внутри одной функции), на что интерпретатор фатально сломался:

Код
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check
Aborted
Экспериментальным путём наблюл, что сие падени из-за наличия второй функции. Удалил всю func2, после чего падаем:

Код
basin: Interpreter/intermediate/value.cpp:193: Value Value::operator+(const Value&): Assertion `0' failed.
Aborted
Это уже из-за работы с переменной loc внутри функции

В общем, так и не получилось что-то вменяемое протестировать. Скачивал tar.gz по ссылке из первого поста. Неплохо было бы, чтобы интерпретатор умел печатать свою версию (которая, например, совпадала бы с номером ревизии). Как сделать так, чтобы svn автоматически писал нормер ревизии в файл - навскидку не помню, но вечером могу из дома ссылку прислать

Добавлено через 1 минуту
Странно, но форум заменил "loc" на "LOC" - видимо какое-то ключевое слово. Но суть от этого не меняется (вместо "loc" можно написать "venik")
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
25.10.2010, 22:34  [ТС]     Пишем свой интерпретатор языка BASIC #392
Действительно,о таком случае последовательного вызова я как-то даже и не подумал . Надо глянуть.
Видимо,там дело в том,что при построении дерева функции func1 func2 ещё не известна,нужно делать похожую вещь,как с метками,проверяя соответствие вызовов с определениями.
Странно,но у меня почему-то после удаления func2 выдаёт-таки ошибку: file:source_err.bas line:5 error: Undefined symbol: LOC на код:
код
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DIM SHARED glob AS INTEGER
LET glob = 10
 
SUB func1
  LET loc = loc + 1
  PRINT "func1: glob="; glob; "; loc="; loc
  LET glob = glob - 1
  IF glob > 0 THEN
    CALL func1
  END IF 
END SUB
 
CALL func1
 
PRINT "main end: glob="; glob; "; loc="; loc

Добавлено позже:
Я походу,так увлёкся функциями,что или сломал что-то,или до этого так и было : у меня ошибку на LOC выдавало потому,что интерпретатор запущен с опцией --noinit-errors,а по идее там должна быть инициализация нулём в выражении... и она даже есть,просто механизм функций всё поменял. Буду исправлять.

Про сборку:
Я пытался сделать,чтобы при отсутствии Qt собиралась только косольная программа,в итоге я так и не смог этого добиться,судя по твоим логам. Всё это я пытался проделать в Makefile.
Насчёт предупреждений,я как раз думал,как лучше сделать.До сих пор с сомнениях.
Дело в том,что в программе неудачно реализован "менеджмент" памяти.Есть шаблонная функция memalloc() которая принимает неинициализированный указатель,а возвращает инициализированный+подсчитывает количество выделенной памяти.Это,в свою очередь,вызывает кучу предупреждений о том что в функцию посылается неинициализированный указатель. Очень мозолит глаза Вот теперь не знаю,как же быть,прокручиваю все варианты(autoptr и другое пока использовать неохота).Думал сделать специальный интерфейс выделения памяти,но тоже получается не очень красиво:
C++
1
pool.alloc(memory::alloctype::STATEMENT)
Что-то типа того,но проблема в том,что при добавлении нового типа нужно будет залезть в enum,а также в функцию alloc,и ещё в том,что alloc будет типа void *.А если делать по функции на каждый тип,то будет много функций-тоже криво.Нужно добиться жёсткого конроля памяти,и в то же время не испортить то,что уже есть..
Это что, в бэйсике так придумано?
Я,честно говоря,точно не понял,как там на самом деле,ибо на разных ресурсах пишут по-разному. Но вроде qbasicstation авторитетный ресурс,и если я правильно понял английский текст,то так и сделал.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
26.10.2010, 00:06     Пишем свой интерпретатор языка BASIC #393
По поводу неинициализированной переменной - у меня выдало то, что я показывал. Я интерпретатор ручками запускал, может ты из-под IDE, а потому у тебя опция принудительно подаётся

Про сборку - это я так, заметил и написал, чтобы не потерялось. Понятно, что на данном этапе сие совсем не горит

Про менеджер памяти - ничего не понял. Зачем подавать туда неинициализированный указатель
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
26.10.2010, 00:32  [ТС]     Пишем свой интерпретатор языка BASIC #394
Цитата Сообщение от Evg Посмотреть сообщение
По поводу неинициализированной переменной - у меня выдало то, что я показывал.
Я уже примерно понял,в чём там ошибка. Связано с ранним выделением памяти под Value для переменной (в случае,если она участвует в выражении,но встречается впервые),ещё на этапе построения дерева,что не правильно. И далее идёт бардак с типизацией,потому что в функциях у меня все значения выделяются блоком и типизация немного недоработана.

Цитата Сообщение от Evg Посмотреть сообщение
Про менеджер памяти - ничего не понял. Зачем подавать туда неинициализированный указатель
А что,инициализировать его NULL сначала? Функция memalloc выглядит примерно так
memalloc
C++
1
2
3
4
5
6
  template <typename T> T *memalloc (T *object)
  {
     allocated += sizeof(T);
     if (allocated > maxallocated) maxallocated = allocated;
     return object = new T;
  }
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
26.10.2010, 13:25     Пишем свой интерпретатор языка BASIC #395
Цитата Сообщение от #pragma Посмотреть сообщение
Функция memalloc выглядит примерно так
Бред какой-то. Это такое стандартное средство Си++ для работы с памятью чтоли?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
26.10.2010, 17:19     Пишем свой интерпретатор языка BASIC #396
Evg, Аллокатор есть. Но насколько я знаю он выглядит не совсем так. Разрабатывал свой простенький для вектора.
Аллокатор
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <limits>
 
#ifndef _ALLOCATOR_H_
#define _ALLOCATOR_H_
 
namespace SimpleSTL
{
    template<class AllocType>
    class Allocator
    {
    public:
        typedef AllocType value_type;
        typedef AllocType* pointer;
        typedef AllocType& reference;
        typedef const AllocType* const_pointer;
        typedef const AllocType& const_reference;
        typedef size_t size_type;
        typedef ptrdiff_t difference_type;
 
        Allocator() throw()
        {
        }
 
        Allocator(const Allocator&) throw()
        {
        }
 
        template<class OtherAlType>
        Allocator(const Allocator<OtherAlType>&) throw()
        {
        }
        
        ~Allocator()
        {
        }
 
        Allocator& operator =(const Allocator&)
        {
            return *this;
        }
 
        pointer adress (reference ref) const
        {
            return (&ref);
        }
 
        const_pointer adress (const_reference ref) const
        {
            return (&ref);
        }
 
        pointer allocate (size_type sz, const_pointer hint=0)
        {
            return new AllocType[sz];
        }
 
        void deallocate (pointer p, size_type)
        {
            delete[] p;
        }
 
        const size_type max_size () const throw()
        {
            return std::numeric_limits<AllocType>::max();
        }
 
        pointer construct (pointer p, const_reference val)
        {
            return new(p) AllocType(val);
        }
 
        void destroy (pointer p)
        {
            p->~AllocType();
        }
 
        template<class OtherAlType>
        struct rebind
        {
            typedef Allocator<OtherAlType> other;
        };
    };
 
    template<class AllocType>
    bool operator ==(const Allocator<AllocType>&, const Allocator<AllocType>&) throw()
    {
        return true;
    }
 
    template<class AllocType>
    bool operator !=(const Allocator<AllocType>&, const Allocator<AllocType>&) throw()
    {
        return false;
    }
}
 
#endif /*_ALLOCATOR_H_*/
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
26.10.2010, 17:35     Пишем свой интерпретатор языка BASIC #397
можно записать так:
C++
1
2
3
4
5
6
template <typename T>
T *memalloc() {
     allocated += sizeof(T);
     if (allocated > maxallocated) maxallocated = allocated;
     return new T;
}
использовать так:
C++
1
2
3
anytype* p = memalloc<anytype>();
// если компилятор поддерживает расширения c++0x, то так:
auto p = memalloc<anytype>();
в данном случае, тип T не может иметь аргументов конструктора. это нормально?

Добавлено через 37 секунд
Цитата Сообщение от Lavroff Посмотреть сообщение
свой простенький
все когда-то писали аллокатор, как и строку
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
26.10.2010, 17:44     Пишем свой интерпретатор языка BASIC #398
Аллокатор это что? Такая хрень, которая подаётся параметром в шаблон контейнера?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
26.10.2010, 17:45     Пишем свой интерпретатор языка BASIC #399
Evg, Ну да. Менеджер памяти.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.10.2010, 17:54     Пишем свой интерпретатор языка BASIC
Еще ссылки по теме:

Пишем свой чекер C++
Не удается откомпилировать интерпретатор М-языка C++
Пишем свой класс, спецификатор доступа protected C++

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

Или воспользуйтесь поиском по форуму:
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
26.10.2010, 17:54     Пишем свой интерпретатор языка BASIC #400
Цитата Сообщение от Lavroff Посмотреть сообщение
Менеджер памяти.
ну нет..
аллокатор берет на себя ответственность по конструированию/инициализации типов, и деаллокацию. ничего более. это же не memory pool.

Добавлено через 1 минуту
Цитата Сообщение от niXman Посмотреть сообщение
деаллокацию
это тоже не всегда справедливо. зависит от типа.
Yandex
Объявления
26.10.2010, 17:54     Пишем свой интерпретатор языка BASIC
Закрытая тема Создать тему
Опции темы

Текущее время: 19:55. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru