Skip to content

Commit 50dc48c

Browse files
committed
WIPO FPACK not working yet
1 parent b009dfa commit 50dc48c

5 files changed

Lines changed: 339 additions & 88 deletions

File tree

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ Current state of the project: **prototype**
3030

3131
Ближайшая цель это **версия 0.1**, в которой:
3232
- подмножество языка с типами Integer и Single, без массивов, строки только константные
33-
- полноценный парсинг всех конструкций языка, кроме оператора `DATA`
33+
- полноценный разбор всех конструкций языка
3434
- вычисление Integer и Single выражений, вычисление константных String выражений
35-
- `PRINT` для Integer/Single и константных строк, `INPUT` только для целых чисел
36-
- функции: `PI`, `ABS`, `FIX`, `INT`, `SGN`, `CINT`, `CSNG`, `PEEK`, `INP`, `SQR`, `SIN`, `COS`, `TAN`, `ATN`, `RND`
37-
- операторы: `LET` (кроме `LET MID$`), `GOTO`, `GOSUB`, `RETURN`, `IF/THEN/ELSE`, `FOR`, `NEXT`, `ON/GOTO/GOSUB`, `STOP`, `END`, `REM`, `PRINT` (включая `AT`, `TAB`, `SPC`, запятая), `INPUT` (только для Integer), `POKE`, `OUT`, `CLS`, `COLOR`, `LOCATE`, `BEEP`
38-
- без работы со строками, без работы с файлами, без графики, без `DATA`/`READ`/`RESTORE`
39-
- НЕ реализованы функции:, `CSRLIN`, `POS`, `EXP`, `LOG`, `FRE`, `CDBL`, `ASC`, `CHR$`, `LRN`, `MID$`, `STRING$`, `VAL`, `INKEY$`, `STR$`, `BIN$`, `OCT$`, `HEX$`, `LPOS`, `EOF`, `FN`, `USR`
40-
- НЕ реализованы операторы: `LET MID$`, `DIM`, `KEY`, `CLEAR`, `DATA`, `READ`, `RESTORE`, `DEF USR`, `DEF FN`, `PRINT` для строковых выражений, `INPUT` для Single и строк, `OPEN`, `CLOSE`, `SCREEN`, `PSET`, `PRESET`, `LINE`, `CIRCLE`, `PAINT`, `DRAW`, `TRON`, `TROFF`, `WIDTH`, `SYSTEM`, `MONIT`
35+
- `PRINT` для Integer/Single и константных строк, `INPUT` только для Integer
36+
- функции: `PI`, `ABS`, `FIX`, `INT`, `SGN`, `CINT`, `CSNG`, `PEEK`, `INP`, `SQR`, `SIN`, `COS`, `TAN`, `ATN`, `RND`, `ASC`, `LEN`, `INKEY$`
37+
- операторы: `LET` (кроме `LET MID$`), `GOTO`, `GOSUB`, `RETURN`, `IF/THEN/ELSE`, `FOR`, `NEXT`, `ON/GOTO/GOSUB`, `STOP`, `END`, `REM`, `PRINT` (включая `AT`, `TAB`, `SPC`, запятая), `INPUT` (только для Integer), `POKE`, `OUT`, `CLS`, `COLOR`, `LOCATE`, `BEEP`, `DATA`, `READ`, `RESTORE`
38+
- без работы с динамическими строками, без работы с файлами, без графики
39+
- НЕ реализованы функции:, `CSRLIN`, `POS`, `EXP`, `LOG`, `FRE`, `CDBL`, `CHR$`, `MID$`, `STRING$`, `VAL`, `STR$`, `BIN$`, `OCT$`, `HEX$`, `LPOS`, `EOF`, `FN`, `USR`
40+
- НЕ реализованы операторы: `LET MID$`, `DIM`, `KEY`, `CLEAR`, `DEF USR`, `DEF FN`, `PRINT` для строковых выражений, `INPUT` для Single и строк, `OPEN`, `CLOSE`, `SCREEN`, `PSET`, `PRESET`, `LINE`, `CIRCLE`, `PAINT`, `DRAW`, `TRON`, `TROFF`, `WIDTH`, `SYSTEM`, `MONIT`
4141

4242
Возможные сценарии использования компилятора:
4343

@@ -96,8 +96,8 @@ VARIA: .WORD 0 ; A%
9696
### Особенности этой реализации
9797

9898
Так же, как и в оригинале Бейсик Вильнюс:
99-
- Один оператор на строку.
100-
- Имена переменных опознаются по двум первым буквам + тип.
99+
- Только один оператор на строку.
100+
- Имена переменных опознаются по двум первым буквам + тип. Переменная без указания знака типа (например: `A`) считается вещественного типа. `A%`, `A`, `A$` - это три разных переменных трёх разных типов. `A` и `A!` - одна и та же переменная вещественного типа.
101101
- Булевого типа нет, вместо него используется целый тип. Результат логических операторов (`=`, `<>`, `>`, `<` и т.п.) это либо `-1` ("истина") либо `0` ("ложь").
102102

103103
Отличия от оригинала:

generator.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ const GeneratorFuncSpec Generator::m_funcspecs[] =
114114
{ KeywordSGN, &Generator::GenerateFuncSgn },
115115
{ KeywordCSNG, &Generator::GenerateFuncCsng },
116116
{ KeywordASC, &Generator::GenerateFuncAsc },
117+
{ KeywordCHR, &Generator::GenerateFuncChr },
117118
{ KeywordIIF, &Generator::GenerateFuncIif },
118119
};
119120

@@ -788,7 +789,7 @@ void Generator::GenerateAssignment(VariableExpressionModel& var, ExpressionModel
788789

789790
if (expr.IsConstExpression())
790791
{
791-
if (vtype == ValueTypeInteger)
792+
if (vtype == ValueTypeInteger && expr.GetExpressionValueType() == ValueTypeInteger)
792793
{
793794
int ivalue = (int)std::floor(expr.GetConstExpressionDValue());
794795
if (ivalue == 0)
@@ -800,7 +801,7 @@ void Generator::GenerateAssignment(VariableExpressionModel& var, ExpressionModel
800801
AddLine("\tMOV\t" + svalue + ", " + deconame + comment);
801802
}
802803
}
803-
else if (vtype == ValueTypeSingle) // const Single
804+
else if (vtype == ValueTypeSingle && expr.GetExpressionValueType() == ValueTypeSingle) // const Single
804805
{
805806
float fvalue = static_cast<float>(expr.GetConstExpressionDValue());
806807
string comment = "\t; var " + canoname + " = const " + to_string_float(static_cast<float>(expr.GetConstExpressionDValue()));
@@ -820,11 +821,18 @@ void Generator::GenerateAssignment(VariableExpressionModel& var, ExpressionModel
820821
AddRuntimeCall(RuntimeSTCP, "var " + canoname + " assignment");
821822
}
822823
}
823-
else if (expr.IsVariableExpression())
824+
else if (expr.IsVariableExpression() && expr.GetExpressionValueType() == ValueTypeInteger && vtype == ValueTypeInteger)
824825
{
825826
string svalue = expr.GetVariableExpressionDecoratedName();
826827
AddLine("\tMOV\t" + svalue + ", " + deconame + comment);
827828
}
829+
else if (expr.IsVariableExpression() && expr.GetExpressionValueType() == ValueTypeSingle && vtype == ValueTypeSingle)
830+
{
831+
string svalue = expr.GetVariableExpressionDecoratedName();
832+
AddLine("\tMOV\t" + svalue + ", " + deconame + comment);
833+
AddLine("\tMOV\t" + svalue + "+2, " + deconame + "+2");
834+
}
835+
//TODO: String var = String var
828836
else // non-const, non-variable
829837
{
830838
ExpressionNode& root = expr.nodes[expr.root];
@@ -3113,6 +3121,7 @@ void Generator::GenerateFuncLog(const ExpressionModel& expr, const ExpressionNod
31133121
// result is String
31143122
void Generator::GenerateFuncInkey(const ExpressionModel& expr, const ExpressionNode& node)
31153123
{
3124+
//TODO: Rework to return dynamic String
31163125
AddRuntimeCall(RuntimeINKEY); // R0 = string address
31173126
}
31183127

@@ -3133,6 +3142,22 @@ void Generator::GenerateFuncAsc(const ExpressionModel& expr, const ExpressionNod
31333142
AddLine("\tBISB\t(R1), R0\t; ASC"); // get first byte of the string
31343143
}
31353144

3145+
// X¤=CHR¤(<АРГУМЕНТ>)
3146+
// result is String
3147+
void Generator::GenerateFuncChr(const ExpressionModel& expr, const ExpressionNode& node)
3148+
{
3149+
//TODO: Special case for const expression and variable expression
3150+
const ExpressionModel& expr1 = node.args[0];
3151+
assert(expr1.GetExpressionValueType() != ValueTypeString);
3152+
3153+
GenerateExpression(expr1);
3154+
if (expr1.GetExpressionValueType() == ValueTypeSingle)
3155+
AddRuntimeCall(RuntimeFTOI, "to Integer"); // result in R0
3156+
3157+
//TODO: Allocate dynamic 1-char string
3158+
//TODO: String length = 1, MOVB R0 to first char of the string
3159+
}
3160+
31363161
// X=IIF(<ЛОГИЧЕСКОЕ ВЫРАЖЕНИЕ>,<АРИФМЕТИЧЕСКОЕ ВЫРАЖЕНИЕ>,<АРИФМЕТИЧЕСКОЕ ВЫРАЖЕНИЕ>)
31373162
// result is Single or Integer
31383163
void Generator::GenerateFuncIif(const ExpressionModel& expr, const ExpressionNode& node)

main.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ enum ValueType
8989
ValueTypeNone = 0,
9090
ValueTypeInteger = 1, // Integer value in range -32768..32767
9191
ValueTypeSingle = 2, // Float value single precision, 4 bytes
92-
//ValueTypeDouble = 3, // Float value double precision, 8 bytes (maybe in the future)
9392
ValueTypeString = 4, // String of length 0..255
93+
ValueTypeDouble = 10, // Float value double precision, 8 bytes (maybe in the future)
9494
};
9595

9696
enum FileMode
@@ -132,17 +132,17 @@ enum RuntimeSymbol
132132
RuntimeIDIV = 19,
133133
RuntimeITOF = 20, // Integer to Single conversion
134134
RuntimeFTOI = 21, // Single to Integer conversion
135-
RuntimeFUNPK = 22, // Print Single to buffer
136-
RuntimeFFIX = 23,
137-
RuntimeFINT = 24,
138-
RuntimeFCMP = 25, // Compare two Single values
139-
RuntimeFSGN = 26,
140-
RuntimeReserved3 = 27,
135+
RuntimeDAUG5 = 22, // Utility procedures for FUNPK/FPACK
136+
RuntimeFUNPK = 23, // Print Single to buffer
137+
RuntimeFFIX = 24,
138+
RuntimeFINT = 25,
139+
RuntimeFCMP = 26, // Compare two Single values
140+
RuntimeFSGN = 27,
141141
RuntimeFADD = 28, // FIS
142142
RuntimeFSUB = 29, // FIS
143143
RuntimeFMUL = 30, // FIS
144144
RuntimeFDIV = 31, // FIS
145-
RuntimeReserved4 = 32,
145+
RuntimeFPACK = 32, // Parse Single from buffer
146146
RuntimeINPF = 33, // INPUT Single
147147
RuntimeReserved5 = 34,
148148
RuntimeFRND = 35, // Random number
@@ -779,6 +779,7 @@ class Generator
779779
void GenerateFuncSgn(const ExpressionModel& expr, const ExpressionNode& node);
780780
void GenerateFuncCsng(const ExpressionModel& expr, const ExpressionNode& node);
781781
void GenerateFuncAsc(const ExpressionModel& expr, const ExpressionNode& node);
782+
void GenerateFuncChr(const ExpressionModel& expr, const ExpressionNode& node);
782783
void GenerateFuncIif(const ExpressionModel& expr, const ExpressionNode& node);
783784
};
784785

model.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -581,12 +581,11 @@ const char* RuntimeSymbolNames[] = {
581581
"INPI",
582582
"IMUL", "IDIV",
583583
"ITOF", "FTOI",
584+
"DAUG5",
584585
"FUNPK", "FFIX", "FINT",
585586
"FCMP", "FSGN",
586-
"", // Reserved
587587
"FADD", "FSUB", "FMUL", "FDIV", // FIS
588-
"", // Reserved
589-
"INPF",
588+
"FPACK", "INPF",
590589
"", // Reserved
591590
"FRND", "FSQR", "FPWF", "FPWI",
592591
"FCOS", "FSIN", "FTAN", "FATN", "FEXP", "FLOG",

0 commit comments

Comments
 (0)