Skip to content

Commit 9a0302c

Browse files
committed
CALL <LABEL>
1 parent e533d6b commit 9a0302c

6 files changed

Lines changed: 48 additions & 7 deletions

File tree

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,18 @@ VARIA: .WORD 0 ; A%
9696
Так же, как и в оригинале Бейсик Вильнюс:
9797
- Один оператор на строку.
9898
- Имена переменных опознаются по двум первым буквам + тип.
99-
- Булевого типа нет, вместо него используется целый тип. Результат логических операторов (`=`, `<>`, `>`, `<` и т.п.) это либо -1 ("истина") либо 0 ("ложь").
99+
- Булевого типа нет, вместо него используется целый тип. Результат логических операторов (`=`, `<>`, `>`, `<` и т.п.) это либо `-1` ("истина") либо `0` ("ложь").
100100

101101
Отличия от оригинала:
102102
- Ключевые слова нужно писать полностью, сокращения НЕ допускаются.
103-
- Для величин/переменных вещественного типа есть только тип Single (32 бита, 7 десятичных цифр). Числа двойной точности (например, `1234#` или `235.988D-7`) в тексте программы НЕ распознаются. Нет функции `CDBL`. Значение `PI` используется в точности Single. Все функции с вещественным результатом также отдают тип Single.
104-
- Номера строк НЕ являются обязательными, они нужны только в случаях, когда на строку нужно сослаться в `GOTO`/`GOSUB`/`ON` и других операторах; исключение: в строке с `FOR` номер нужно указывать.
103+
- Для величин/переменных вещественного типа есть только тип "одинарной точности" (Single, 32 бита, 7 десятичных цифр). Числа двойной точности (например, `1234#` или `235.988D-7`) в тексте программы НЕ распознаются. Нет функции `CDBL`. Значение `PI` используется в точности Single. Все функции с вещественным результатом также отдают тип Single.
104+
- Номера строк НЕ являются обязательными, они нужны только в случаях, когда на строку нужно сослаться в `GOTO`/`GOSUB`/`ON` и других операторах.
105105
- Под оператором `IF` в `THEN`/`ELSE` НЕ допускается ставить операторы `FOR`/`NEXT`/`DIM`/`DATA`
106106
- Аргумент функций `CSRLIN` и `POS` необязательный, но если есть, то вычисляется (если он не константный), но результат вычисления не используется.
107107
- `ON .. GOTO/GOSUB`: отрицательное значение выражения под `ON` не приводит к ошибке, просто переходим на строку, следующую после этого оператора.
108108
- Добавлена функция `IIF` с тремя аргументами: `X=IIF(<ЛОГ.ВЫРАЖЕНИЕ>,<АРИФМ.ВЫРАЖЕНИЕ>,<АРИФМ.ВЫРАЖЕНИЕ>)`. Вычисляется первый аргумент; если он ненулевой (т.е. TRUE), то результатом будет значение второго выражения, иначе (для FALSE) - значение третьего выражения. Вычисляется только то выражение, результат которого будет использоваться. Тип результата зависит от типов второго и третьего аргументов: если они оба Integer, то и результат Integer; если хотя бы один из них Single, то и результат Single.
109-
- Команды/операторы, которые не реализованы и НЕ БУДУТ реализованы в будущем:
109+
- `CALL <МЕТКА>` генерирует вызов подпрограммы в машинных кодах с указанной меткой. Предполагается, что эти подпрограммы будут оформляться в виде отдельного модуля на MACRO/BKTurbo8 и подключаться к программе на этапе линковки.
110+
- Команды/операторы, которые НЕ реализованы и НЕ БУДУТ реализованы в будущем:
110111
- `RUN`, `CONT`
111112
- `KEY` (переназначение функциональных клавиш)
112113
- `LOAD`, `SAVE`, `CLOAD`, `CSAVE` (загрузка и сохранение текста программы)

generator.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const GeneratorKeywordSpec Generator::m_keywordspecs[] =
5353
{ KeywordTRON, &Generator::GenerateIgnoredStatement },
5454
{ KeywordTROFF, &Generator::GenerateIgnoredStatement },
5555
{ KeywordWIDTH, &Generator::GenerateWidth },
56+
{ KeywordCALL, &Generator::GenerateCall },
5657
};
5758

5859
GeneratorMethodRef Generator::FindGeneratorMethodRef(KeywordIndex keyword)
@@ -1736,6 +1737,15 @@ void Generator::GenerateWidth(StatementModel& statement)
17361737
Warning(statement.token, "WIDTH statement is ignored");
17371738
}
17381739

1740+
// Extension: calls assembler procedure
1741+
// CALL <LABEL>
1742+
void Generator::GenerateCall(StatementModel& statement)
1743+
{
1744+
if (!g_turbo8)
1745+
AddLine("\t.GLOBL\t" + statement.ident.text);
1746+
AddLine("\tCALL\t" + statement.ident.text + "\t; CALL label");
1747+
}
1748+
17391749

17401750
// Operation generation //////////////////////////////////////////////
17411751

main.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ typedef std::string string;
3333
//////////////////////////////////////////////////////////////////////
3434
// Enums
3535

36+
//NOTE: This enum should be in the same order as Keywords array in tokenizer.cpp
3637
enum KeywordIndex
3738
{
3839
KeywordNone = 0,
3940
KeywordABS, KeywordAND, KeywordASC, KeywordAT, KeywordATN, KeywordAUTO,
4041
KeywordBEEP, KeywordBLOAD, KeywordBSAVE, KeywordBIN,
41-
KeywordCDBL, KeywordCHR, KeywordCINT, KeywordCIRCLE, KeywordCLEAR, KeywordCLOAD, KeywordCLS,
42+
KeywordCALL, KeywordCDBL, KeywordCHR, KeywordCINT, KeywordCIRCLE, KeywordCLEAR, KeywordCLOAD, KeywordCLS,
4243
KeywordCOLOR, KeywordCONT, KeywordCOS, KeywordCSAVE, KeywordCSNG, KeywordCSRLIN, KeywordCLOSE, KeywordSCREEN,
4344
KeywordDELETE, KeywordDIM, KeywordDRAW, KeywordDATA, KeywordDEF,
4445
KeywordELSE, KeywordEND, KeywordEOF, KeywordEQV, KeywordEXP,
@@ -293,7 +294,7 @@ struct VariableExpressionModel : VariableBaseModel
293294
struct StatementModel
294295
{
295296
Token token; // Token for the statement keyword
296-
Token ident; // LET identifier at left, FOR variable
297+
Token ident; // LET identifier at left, FOR variable, CALL label
297298
int paramline; // Line number parameter for GOTO, GOSUB, RESTORE
298299
bool inner; // Is it inner statement under THEN or ELSE
299300
bool relative; // PSET, PRESET, LINE, CIRCLE, PAINT with '@' sign
@@ -471,6 +472,7 @@ class Parser
471472
void ParseRestore(StatementModel& statement);
472473
void ParseScreen(StatementModel& statement);
473474
void ParseWidth(StatementModel& statement);
475+
void ParseCall(StatementModel& statement);
474476
};
475477

476478
class Validator;
@@ -553,6 +555,7 @@ class Validator
553555
void ValidateRestore(StatementModel& statement);
554556
void ValidateScreen(StatementModel& statement);
555557
void ValidateWidth(StatementModel& statement);
558+
void ValidateCall(StatementModel& statement);
556559
private:
557560
void ValidateUnaryPlus(ExpressionModel& expr, ExpressionNode& node, const ExpressionNode& noderight);
558561
void ValidateUnaryMinus(ExpressionModel& expr, ExpressionNode& node, const ExpressionNode& noderight);
@@ -709,6 +712,7 @@ class Generator
709712
void GenerateScreen(StatementModel& statement);
710713
void GenerateStop(StatementModel& statement);
711714
void GenerateWidth(StatementModel& statement);
715+
void GenerateCall(StatementModel& statement);
712716
private:
713717
void GenerateOperPlus(const ExpressionModel& expr, const ExpressionNode& node, const ExpressionNode& nodeleft, const ExpressionNode& noderight);
714718
void GenerateOperMinus(const ExpressionModel& expr, const ExpressionNode& node, const ExpressionNode& nodeleft, const ExpressionNode& noderight);

parser.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const ParserKeywordSpec Parser::m_keywordspecs[] =
5757
{ KeywordTROFF, &Parser::ParseStatementNoParams },
5858
{ KeywordTRON, &Parser::ParseStatementNoParams },
5959
{ KeywordWIDTH, &Parser::ParseWidth },
60+
{ KeywordCALL, &Parser::ParseCall },
6061
};
6162

6263
const ParserFunctionSpec Parser::m_funcspecs[] =
@@ -2022,5 +2023,21 @@ void Parser::ParseWidth(StatementModel& statement)
20222023
MODEL_ERROR(MSG_UNEXPECTED_AT_END_OF_STATEMENT);
20232024
}
20242025

2026+
// Extension: calls assembler procedure
2027+
// CALL <LABEL>
2028+
void Parser::ParseCall(StatementModel& statement)
2029+
{
2030+
Token token = PeekNextTokenSkipDivider();
2031+
if (token.type != TokenTypeIdentifier)
2032+
MODEL_ERROR("CALL label expected.");
2033+
GetNextToken();
2034+
2035+
statement.ident = token;
2036+
2037+
token = PeekNextTokenSkipDivider();
2038+
if (!token.IsEndOfStatement())
2039+
MODEL_ERROR(MSG_UNEXPECTED_AT_END_OF_STATEMENT);
2040+
}
2041+
20252042

20262043
//////////////////////////////////////////////////////////////////////

tokenizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
const char* Keywords[] = {
99
"ABS", "AND", "ASC", "AT", "ATN", "AUTO",
1010
"BEEP", "BLOAD", "BSAVE", "BIN$",
11-
"CDBL", "CHR$", "CINT", "CIRCLE", "CLEAR", "CLOAD", "CLS",
11+
"CALL", "CDBL", "CHR$", "CINT", "CIRCLE", "CLEAR", "CLOAD", "CLS",
1212
"COLOR", "CONT", "COS", "CSAVE", "CSNG", "CSRLIN", "CLOSE", "SCREEN",
1313
"DELETE", "DIM", "DRAW", "DATA", "DEF",
1414
"ELSE", "END", "EOF", "EQV", "EXP",

validator.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const ValidatorKeywordSpec Validator::m_keywordspecs[] =
5757
{ KeywordTRON, &Validator::ValidateNothing },
5858
{ KeywordDEF, &Validator::ValidateDef },
5959
{ KeywordWIDTH, &Validator::ValidateWidth },
60+
{ KeywordCALL, &Validator::ValidateCall },
6061
};
6162

6263
const ValidatorOperSpec Validator::m_operspecs[] =
@@ -1160,6 +1161,13 @@ void Validator::ValidateWidth(StatementModel& statement)
11601161
//NOTE: Ignored for now
11611162
}
11621163

1164+
// Extension: calls assembler procedure
1165+
// CALL <LABEL>
1166+
void Validator::ValidateCall(StatementModel& statement)
1167+
{
1168+
if (statement.ident.type != TokenTypeIdentifier)
1169+
MODEL_ERROR("Identifier expected.");
1170+
}
11631171

11641172
// Operation validation //////////////////////////////////////////////
11651173
// Every operation validator function should:
@@ -2290,6 +2298,7 @@ void Validator::ValidateFuncPoint(ExpressionModel& expr, ExpressionNode& node)
22902298
node.constval = false;
22912299
}
22922300

2301+
// Extension: conditional function
22932302
// X=IIF(<ЛОГИЧЕСКОЕ ВЫРАЖЕНИЕ>,<АРИФМЕТИЧЕСКОЕ ВЫРАЖЕНИЕ>,<АРИФМЕТИЧЕСКОЕ ВЫРАЖЕНИЕ>)
22942303
// result is Single or Integer
22952304
void Validator::ValidateFuncIif(ExpressionModel& expr, ExpressionNode& node)

0 commit comments

Comments
 (0)