Skip to content

Commit cca72fb

Browse files
committed
Runtime blocks INIT/TERM
1 parent 9a0302c commit cca72fb

8 files changed

Lines changed: 129 additions & 61 deletions

File tree

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,10 @@ Current state of the project: **prototype**
6767
Результат компиляции (только основной код, без рантайма):
6868
```assembler
6969
START:
70-
MTPS #340 ; disable interrupts
70+
; Инициализация программы
71+
MTPS #340 ; disable interrupts
7172
CLR @#177560
72-
MTPS #0 ; enable interrupts
73+
MTPS #0 ; enable interrupts
7374
MOV SP, SAVESP
7475
; 10 A%=23.42
7576
N10:
@@ -80,6 +81,7 @@ N20:
8081
CALL WRINT ; PRINT Integer
8182
CALL WREOL
8283
LEND:
84+
; Завершение программы
8385
SAVESP = . + 2
8486
MOV #776, SP ; restore SP
8587
EMT 350 ; .EXIT

generator.cpp

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,15 @@ static string GET_CONSTEXPR_INT_VALUE_AS_CLRMOV(ExpressionModel expr)
195195
//////////////////////////////////////////////////////////////////////
196196

197197

198-
Generator::Generator(SourceModel* source, FinalModel* final)
199-
: m_source(source), m_final(final), m_lineindex(-1), m_line(nullptr),
200-
m_runtimeneeds(), m_notimplemented()
198+
Generator::Generator(SourceModel* source, FinalModel* final,
199+
const std::vector<string>* initlines, const std::vector<string>* termlines)
200+
: m_source(source), m_final(final), m_initlines(initlines), m_termlines(termlines),
201+
m_lineindex(-1), m_line(nullptr), m_local(0), m_runtimeneeds(), m_notimplemented()
201202
{
202203
assert(source != nullptr);
203204
assert(final != nullptr);
205+
assert(initlines != nullptr);
206+
assert(termlines != nullptr);
204207
}
205208

206209
void Generator::AddRuntimeCall(RuntimeSymbol rtsymbol, string comment)
@@ -226,25 +229,14 @@ void Generator::AddRuntimeCall(RuntimeSymbol rtsymbol, string comment)
226229
void Generator::ProcessBegin()
227230
{
228231
AddLine("START:");
229-
if (g_platform == PlatformUKNC)
230-
{
231-
AddLine("\tMTPS\t#340\t; disable interrupts");
232-
AddLine("\tCLR\t@#177560");
233-
AddLine("\tMTPS\t#0\t; enable interrupts");
234-
}
235-
AddLine("\tMOV\tSP, SAVESP");
232+
233+
// Copy initialization code from the runtime template
234+
for (const string& line : *m_initlines)
235+
m_final->AddLine(line);
236236
}
237237

238238
void Generator::ProcessEnd()
239239
{
240-
AddLine("LEND:");
241-
AddLine("SAVESP = . + 2");
242-
AddLine("\tMOV\t#776, SP\t; restore SP");
243-
if (g_platform == PlatformBK0010)
244-
AddLine("\tRETURN\t; return to Monitor/OS/etc.");
245-
else if (g_platform == PlatformUKNC)
246-
AddLine("\tEMT\t350\t; .EXIT");
247-
248240
// Enumerate all the prepared lines to format them properly
249241
for (string& line : m_final->lines)
250242
{
@@ -270,6 +262,12 @@ void Generator::ProcessEnd()
270262
}
271263
}
272264

265+
AddLine("LEND:");
266+
267+
// Copy termination code from the runtime template
268+
for (const string& line : *m_termlines)
269+
m_final->AddLine(line);
270+
273271
GenerateStrings();
274272

275273
GenerateVariables();

main.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

2+
#include <cassert>
23
#include <cstdio>
34
#include <iostream>
45
#include <fstream>
@@ -50,7 +51,6 @@ TargetPlatform FindPlatformByName(const string& name)
5051
return PlatformNone;
5152
}
5253

53-
5454
void RegisterError()
5555
{
5656
g_errorcount++;
@@ -274,15 +274,6 @@ void ProcessFiles()
274274
exit(EXIT_FAILURE);
275275
}
276276

277-
// Generation
278-
Generator generator(&g_source, &g_final);
279-
g_errorcount = 0;
280-
while (generator.ProcessLine())
281-
;
282-
283-
const std::set<RuntimeSymbol> runtimeneeds = generator.GetRuntimeNeeds();
284-
RuntimeGenerator runtimegen(runtimeneeds, &g_final);
285-
286277
// Read and parse the runtime template
287278
std::ifstream rttplstream;
288279
rttplstream.open(g_rttplfilepath);
@@ -291,11 +282,32 @@ void ProcessFiles()
291282
std::cerr << "Failed to open runtime template file " + g_rttplfilepath << std::endl;
292283
exit(EXIT_FAILURE);
293284
}
285+
RuntimeGenerator runtimegen(&g_final);
294286
runtimegen.ParseRuntimeTemplate(&rttplstream);
295287
rttplstream.close();
296288

289+
// Generation
290+
std::vector<string> initlines;
291+
runtimegen.GetRuntimeBlock(RuntimeINIT, initlines);
292+
std::vector<string> termlines;
293+
runtimegen.GetRuntimeBlock(RuntimeTERM, termlines);
294+
295+
if (g_errorcount > 0)
296+
{
297+
std::cerr << "Generation ERRORS: " << g_errorcount << std::endl;
298+
exit(EXIT_FAILURE);
299+
}
300+
assert(!initlines.empty());
301+
assert(!termlines.empty());
302+
303+
Generator generator(&g_source, &g_final, &initlines, &termlines);
304+
g_errorcount = 0;
305+
while (generator.ProcessLine())
306+
;
307+
297308
// Generate runtime
298-
runtimegen.GenerateRuntime();
309+
const std::set<RuntimeSymbol> runtimeneeds = generator.GetRuntimeNeeds();
310+
runtimegen.GenerateRuntime(runtimeneeds);
299311

300312
if (g_errorcount > 0)
301313
{

main.h

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -107,30 +107,31 @@ enum TargetPlatform
107107
PlatformUKNC = 2,
108108
};
109109

110+
//NOTE: This enum should be in the same order as RuntimeSymbolNames array in model.cpp
110111
enum RuntimeSymbol
111112
{
112113
RuntimeNone = 0,
113-
RuntimeWRCH = 1,
114-
RuntimeWREOL = 2,
115-
RuntimeWRAT = 3,
116-
RuntimeWRSPC = 4,
117-
RuntimeWRTAB = 5,
118-
RuntimeWRCOM = 6,
119-
RuntimeWRINT = 7,
120-
RuntimeWRSNG = 8,
121-
RuntimeWRST = 9, // Write String
122-
RuntimeSTOP = 10, // Show stop message and stop
123-
RuntimeERRR = 11, // Show error message and stop
124-
RuntimeReserved1 = 12,
125-
RuntimeGETCR = 13,
126-
RuntimeCURSR = 14,
127-
RuntimeINPU = 15, // INPUT read to buffer
128-
RuntimeINPI = 16, // INPUT Integer
129-
RuntimeIMUL = 17,
130-
RuntimeIDIV = 18,
131-
RuntimeITOF = 19, // Integer to Single conversion
132-
RuntimeFTOI = 20, // Single to Integer conversion
133-
RuntimeReserved2 = 21,
114+
RuntimeINIT = 1, // Initialization code to copy into the assembly code
115+
RuntimeTERM = 2, // Termination code to copy into the assembly code
116+
RuntimeWRCH = 3,
117+
RuntimeWREOL = 4,
118+
RuntimeWRAT = 5,
119+
RuntimeWRSPC = 6,
120+
RuntimeWRTAB = 7,
121+
RuntimeWRCOM = 8,
122+
RuntimeWRINT = 9,
123+
RuntimeWRSNG = 10,
124+
RuntimeWRST = 11, // Write String
125+
RuntimeSTOP = 12, // Show stop message and stop
126+
RuntimeERRR = 13, // Show error message and stop
127+
RuntimeGETCR = 14,
128+
RuntimeCURSR = 15,
129+
RuntimeINPU = 16, // INPUT read to buffer
130+
RuntimeINPI = 17, // INPUT Integer
131+
RuntimeIMUL = 18,
132+
RuntimeIDIV = 19,
133+
RuntimeITOF = 20, // Integer to Single conversion
134+
RuntimeFTOI = 21, // Single to Integer conversion
134135
RuntimeFUNPK = 22, // Print Single to buffer
135136
RuntimeFFIX = 23,
136137
RuntimeFINT = 24,
@@ -158,6 +159,7 @@ enum RuntimeSymbol
158159
RuntimeINKEY = 46,
159160
RuntimeSTCP = 47, // String copy
160161
RuntimeCOLR = 48, // COLOR
162+
__RuntimeSymbol_SIZE__
161163
};
162164

163165

@@ -639,13 +641,16 @@ class Generator
639641
{
640642
SourceModel* m_source;
641643
FinalModel* m_final;
644+
const std::vector<string>* m_initlines;
645+
const std::vector<string>* m_termlines;
642646
int m_lineindex;
643647
SourceLineModel* m_line; // Curent line being generated
644648
int m_local; // Counter for local labels within the current line
645649
std::set<RuntimeSymbol> m_runtimeneeds;
646650
std::set<KeywordIndex> m_notimplemented; // Statements/functions used but not implemented
647651
public:
648-
Generator(SourceModel* source, FinalModel* intermed);
652+
Generator(SourceModel* source, FinalModel* intermed,
653+
const std::vector<string>* initlines, const std::vector<string>* termlines);
649654
public:
650655
void ProcessBegin();
651656
bool ProcessLine();
@@ -763,10 +768,11 @@ class RuntimeGenerator
763768
FinalModel* m_final;
764769
std::vector<RuntimeBlock> m_rtblocks;
765770
public:
766-
RuntimeGenerator(const std::set<RuntimeSymbol>& needs, FinalModel* intermed);
771+
RuntimeGenerator(FinalModel* intermed);
767772
public:
768773
void ParseRuntimeTemplate(std::istream* pInput);
769-
void GenerateRuntime();
774+
void GenerateRuntime(const std::set<RuntimeSymbol>& needs);
775+
void GetRuntimeBlock(RuntimeSymbol rtsymbol, std::vector<string>& copyto);
770776
private:
771777
RuntimeBlock FindRuntimeBlock(RuntimeSymbol rtsymbol);
772778
void AddLine(const string& str) { m_final->AddRuntimeLine(str); }

model.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -566,17 +566,16 @@ void FinalModel::AddRuntimeLine(const string& str)
566566
// The table has the same procedures in the same order as RuntimeSymbol enum
567567
const char* RuntimeSymbolNames[] = {
568568
"", // None
569+
"INIT", "TERM",
569570
"WRCH", "WREOL", "WRAT", "WRSPC", "WRTAB", "WRCOM",
570571
"WRINT", "WRSNG", "WRST",
571572
"STOP",
572573
"ERRR",
573-
"", // Reserved
574574
"GETCR", "CURSR",
575575
"INPU",
576576
"INPI",
577577
"IMUL", "IDIV",
578578
"ITOF", "FTOI",
579-
"", // Reserved
580579
"FUNPK", "FFIX", "FINT",
581580
"FCMP", "FSGN",
582581
"", // Reserved
@@ -594,6 +593,9 @@ const char* RuntimeSymbolNames[] = {
594593

595594
string GetRuntimeSymbolName(RuntimeSymbol rtsymbol)
596595
{
596+
// Make sure RuntimeSymbolNames array has the same size as RuntimeSymbol enum
597+
assert(__RuntimeSymbol_SIZE__ == sizeof(RuntimeSymbolNames) / sizeof(const char*));
598+
597599
if (rtsymbol < sizeof(RuntimeSymbolNames) / sizeof(const char*))
598600
return RuntimeSymbolNames[rtsymbol];
599601

runtime-BK0010.tmac

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
1-
; Шаблон рантайм процедур для БК-0010
1+
; Шаблон рантайма для БК-0010
22
;
3+
4+
;#####################################################################
5+
;## INIT
6+
; Инициализация программы
7+
MOV SP, SAVESP
8+
9+
;#####################################################################
10+
;## TERM
11+
; Завершение программы
12+
SAVESP = . + 2
13+
MOV #776, SP ; restore SP
14+
RETURN ; return to Monitor/OS/etc.
15+
16+
317
;#####################################################################
418
;## WRCH
519
; Печать одного символа; R0 = символ

runtime-UKNC.tmac

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
; Шаблон рантайм процедур для УКНЦ
22
;
3+
4+
;#####################################################################
5+
;## INIT
6+
; Инициализация программы
7+
MTPS #340 ; disable interrupts
8+
CLR @#177560
9+
MTPS #0 ; enable interrupts
10+
MOV SP, SAVESP
11+
12+
;#####################################################################
13+
;## TERM
14+
; Завершение программы
15+
SAVESP = . + 2
16+
MOV #776, SP ; restore SP
17+
EMT 350 ; .EXIT
18+
19+
320
;#####################################################################
421
;## WRCH
522
; Печать одного символа; R0 = символ

runtime.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
//////////////////////////////////////////////////////////////////////
99

1010

11-
RuntimeGenerator::RuntimeGenerator(const std::set<RuntimeSymbol>& needs, FinalModel* intermed)
12-
: m_needs(needs), m_final(intermed)
11+
RuntimeGenerator::RuntimeGenerator(FinalModel* intermed)
12+
: m_final(intermed)
1313
{
1414
assert(intermed != nullptr);
1515
}
@@ -97,8 +97,25 @@ RuntimeBlock RuntimeGenerator::FindRuntimeBlock(RuntimeSymbol rtsymbol)
9797
return RuntimeBlock(); // empty block
9898
}
9999

100-
void RuntimeGenerator::GenerateRuntime()
100+
void RuntimeGenerator::GetRuntimeBlock(RuntimeSymbol rtsymbol, std::vector<string>& copyto)
101101
{
102+
RuntimeBlock rtblock = FindRuntimeBlock(rtsymbol);
103+
if (rtblock.rtsymbol == RuntimeNone)
104+
{
105+
string rtsymbolname = GetRuntimeSymbolName(rtsymbol);
106+
std::cerr << "Runtime block \'" << rtsymbolname << "\' not found." << std::endl;
107+
RegisterError();
108+
return;
109+
}
110+
111+
std::copy(rtblock.lines.begin(), rtblock.lines.end(), std::back_inserter(copyto));
112+
}
113+
114+
void RuntimeGenerator::GenerateRuntime(const std::set<RuntimeSymbol>& needs)
115+
{
116+
for (RuntimeSymbol rtsymbol : needs)
117+
m_needs.insert(rtsymbol);
118+
102119
std::vector<RuntimeSymbol> listnewneeds;
103120
std::copy(m_needs.begin(), m_needs.end(), std::back_inserter(listnewneeds));
104121
while (true)

0 commit comments

Comments
 (0)