forked from lkesteloot/turbopascal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtpc.js
83 lines (71 loc) · 2.49 KB
/
tpc.js
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
'use strict';
//Error.stackTraceLimit = Infinity;
const CommentStripper = require('./CommentStripper.js');
const Lexer = require('./Lexer.js');
const Parser = require('./Parser.js');
const SymbolTable = require('./SymbolTable.js');
const PascalError = require('./PascalError.js');
const Stream = require('./Stream.js');
const Compiler = require('./Compiler.js');
const Machine = require('./Machine.js');
const ansi = require('ansi')(process.stdout);
function compile(source, run, DEBUG_TRACE) {
let self = this;
if (!source) {
return;
}
let stream = new Stream(source);
let lexer = new CommentStripper(new Lexer(stream));
let parser = new Parser(lexer);
let result = { parsed: false, compiled: false };
try {
// Create the symbol table of built-in constants, functions, and procedures.
let builtinSymbolTable = SymbolTable.makeBuiltinSymbolTable();
// Parse the program into a parse tree. Create the symbol table as we go.
let root = parser.parse(builtinSymbolTable);
result.tree = root.print("");
result.parsed = true;
// Compile to bytecode.
let compiler = new Compiler();
let bytecode = compiler.compile(root);
result.compiled = true;
result.bytecode = bytecode;
result.pSrc = bytecode.print();
if (run) {
// Execute the bytecode.
let machine = new Machine(bytecode, this.keyboard, ansi);
if (DEBUG_TRACE) {
machine.setDebugCallback(function (state) {
$state.append(state + "\n");
});
}
machine.setFinishCallback(function (runningTime) {
});
machine.setOutputCallback(function (line) {
console.log(line);
});
machine.setOutChCallback(function (line) {
process.stdout.write(line);
});
machine.setInputCallback(function (callback) {
self.screen.addCursor();
self._setInputMode(INPUT_STRING, function (line) {
self._setInputMode(INPUT_RUNNING);
callback(line);
});
});
machine.run();
}
} catch (e) {
console.warn(e.message);
// Print parsing errors.
if (e instanceof PascalError) {
console.warn(e.getMessage());
}
console.warn(e.stack);
}
return result;
};
module.exports = {
compile
};