aboutsummaryrefslogtreecommitdiff
path: root/lib/compilers/pascal.js
diff options
context:
space:
mode:
authorPatrick Quist <partouf@gmail.com>2021-09-13 20:22:27 +0200
committerGitHub <noreply@github.com>2021-09-13 20:22:27 +0200
commitbc6757ae94dbc46fa1243f3277de2262794d5a75 (patch)
treed264a83fea30a6b189def084c0d422814b814de3 /lib/compilers/pascal.js
parent3d1a6a672066d5d2b93255ffb7e39a1293bb227c (diff)
downloadcompiler-explorer-bc6757ae94dbc46fa1243f3277de2262794d5a75.tar.gz
compiler-explorer-bc6757ae94dbc46fa1243f3277de2262794d5a75.zip
Pascalchanges (#2881)
* Changes to allow Program (vs Unit) in Object Pascal * add possibility of dpr * more flexibility with pascal filenames * lintfixes * i have no idea what im doing * apply changes to pascal-win * pascal fixes * pascal projectfile changes * work in progress * bugfixes * bla * bugfixes * mostly working Co-authored-by: paul mcgee <paul.mcgee.8@bigpond.com> Co-authored-by: Paul McGee <paulmcgee1969@gmail.com>
Diffstat (limited to 'lib/compilers/pascal.js')
-rw-r--r--lib/compilers/pascal.js119
1 files changed, 93 insertions, 26 deletions
diff --git a/lib/compilers/pascal.js b/lib/compilers/pascal.js
index 605e741ab..136e49190 100644
--- a/lib/compilers/pascal.js
+++ b/lib/compilers/pascal.js
@@ -31,6 +31,7 @@ import { BaseCompiler } from '../base-compiler';
import * as utils from '../utils';
import { PascalParser } from './argument-parsers';
+import { PascalUtils } from './pascal-utils';
export class FPCCompiler extends BaseCompiler {
static get key() {
@@ -41,8 +42,10 @@ export class FPCCompiler extends BaseCompiler {
super(info, env);
this.compileFilename = 'output.pas';
+ this.dprFilename = 'prog.dpr';
this.supportsOptOutput = false;
this.nasmPath = this.compilerProps('nasmpath');
+ this.pasUtils = new PascalUtils();
}
getSharedLibraryPathsAsArguments() {
@@ -78,6 +81,10 @@ export class FPCCompiler extends BaseCompiler {
filters.preProcessLines = _.bind(this.preProcessLines, this);
+ if (filters.binary) {
+ filters.dontMaskFilenames = true;
+ }
+
return options;
}
@@ -90,7 +97,8 @@ export class FPCCompiler extends BaseCompiler {
}
static preProcessBinaryAsm(input) {
- const relevantAsmStartsAt = input.indexOf('<OUTPUT');
+ const systemInitOffset = input.indexOf('<SYSTEM_$$_init$>');
+ const relevantAsmStartsAt = input.indexOf('...', systemInitOffset);
if (relevantAsmStartsAt !== -1) {
const lastLinefeedBeforeStart = input.lastIndexOf('\n', relevantAsmStartsAt);
if (lastLinefeedBeforeStart !== -1) {
@@ -106,22 +114,44 @@ export class FPCCompiler extends BaseCompiler {
return input;
}
- getObjdumpOutputFilename(defaultOutputFilename) {
- return this.getExecutableFilename(path.dirname(defaultOutputFilename));
- }
-
postProcessObjdumpOutput(output) {
return FPCCompiler.preProcessBinaryAsm(output);
}
- async saveDummyProjectFile(filename) {
- const unitName = path.basename(this.compileFilename, this.lang.extensions[0]);
-
+ async saveDummyProjectFile(filename, unitName, unitPath) {
await fs.writeFile(filename,
- 'program prog; ' +
- 'uses ' + unitName + ' in \'' + this.compileFilename + '\'; ' +
- 'begin ' +
- 'end.');
+ 'program prog;\n' +
+ 'uses ' + unitName + ' in \'' + unitPath + '\';\n' +
+ 'begin\n' +
+ 'end.\n');
+ }
+
+ async writeAllFiles(dirPath, source, files, filters) {
+ let inputFilename;
+ if (this.pasUtils.isProgram(source)) {
+ inputFilename = path.join(dirPath, this.dprFilename);
+ } else {
+ const unitName = this.pasUtils.getUnitname(source);
+ if (unitName) {
+ inputFilename = path.join(dirPath, unitName + '.pas');
+ } else {
+ inputFilename = path.join(dirPath, this.compileFilename);
+ }
+ }
+
+ if (source !== '' || !files) {
+ await fs.writeFile(inputFilename, source);
+ }
+
+ if (files) {
+ filters.dontMaskFilenames = true;
+
+ await this.writeMultipleFiles(files, dirPath);
+ }
+
+ return {
+ inputFilename,
+ };
}
async runCompiler(compiler, options, inputFilename, execOptions) {
@@ -129,14 +159,21 @@ export class FPCCompiler extends BaseCompiler {
execOptions = this.getDefaultExecOptions();
}
+ let alreadyHasDPR = path.basename(inputFilename) === this.dprFilename;
const dirPath = path.dirname(inputFilename);
- const projectFile = path.join(dirPath, 'prog.dpr');
+
+ const projectFile = path.join(dirPath, this.dprFilename);
execOptions.customCwd = dirPath;
if (this.nasmPath) {
execOptions.env = _.clone(process.env);
execOptions.env.PATH = execOptions.env.PATH + ':' + this.nasmPath;
}
- await this.saveDummyProjectFile(projectFile);
+
+ if (!alreadyHasDPR) {
+ const unitFilepath = path.basename(inputFilename);
+ const unitName = unitFilepath.replace(/.pas$/i, '');
+ await this.saveDummyProjectFile(projectFile, unitName, unitFilepath);
+ }
options.pop();
options.push('-FE' + dirPath, '-B', projectFile);
@@ -152,17 +189,11 @@ export class FPCCompiler extends BaseCompiler {
return result;
}
- execBinary(executable, maxSize, executeParameters, homeDir) {
- executable = this.getExecutableFilename(path.dirname(executable));
-
- return super.execBinary(executable, maxSize, executeParameters, homeDir);
- }
-
getArgumentParser() {
return PascalParser;
}
- getExtraAsmHint(asm) {
+ getExtraAsmHint(asm, currentFileId) {
if (asm.startsWith('# [')) {
const bracketEndPos = asm.indexOf(']', 3);
let valueInBrackets = asm.substr(3, bracketEndPos - 3);
@@ -171,12 +202,14 @@ export class FPCCompiler extends BaseCompiler {
valueInBrackets = valueInBrackets.substr(0, colonPos - 1);
}
+ if (valueInBrackets.startsWith('/')) {
+ valueInBrackets = valueInBrackets.substr(1);
+ }
+
if (!isNaN(valueInBrackets)) {
- return ' .loc 1 ' + valueInBrackets + ' 0';
- } else if (valueInBrackets.includes(this.compileFilename)) {
- return ' .file 1 "<stdin>"';
+ return ` .loc ${currentFileId} ${valueInBrackets} 0`;
} else {
- return false;
+ return ` .file ${currentFileId} "${valueInBrackets}"`;
}
} else if (asm.startsWith('.Le')) {
return ' .cfi_endproc';
@@ -185,11 +218,45 @@ export class FPCCompiler extends BaseCompiler {
}
}
+ tryGetFilenumber(asm, files) {
+ if (asm.startsWith('# [')) {
+ const bracketEndPos = asm.indexOf(']', 3);
+ let valueInBrackets = asm.substr(3, bracketEndPos - 3);
+ const colonPos = valueInBrackets.indexOf(':');
+ if (colonPos !== -1) {
+ valueInBrackets = valueInBrackets.substr(0, colonPos - 1);
+ }
+
+ if (valueInBrackets.startsWith('/')) {
+ valueInBrackets = valueInBrackets.substr(1);
+ }
+
+ if (isNaN(valueInBrackets)) {
+ if (!files[valueInBrackets]) {
+ let maxFileId = _.max(files);
+ if (maxFileId === -Infinity) {
+ maxFileId = 0;
+ }
+
+ files[valueInBrackets] = maxFileId + 1;
+ return maxFileId + 1;
+ }
+ }
+ }
+
+ return false;
+ }
+
preProcessLines(asmLines) {
let i = 0;
+ let files = {};
+ let currentFileId = 1;
while (i < asmLines.length) {
- const extraHint = this.getExtraAsmHint(asmLines[i]);
+ let newFileId = this.tryGetFilenumber(asmLines[i], files);
+ if (newFileId) currentFileId = newFileId;
+
+ const extraHint = this.getExtraAsmHint(asmLines[i], currentFileId);
if (extraHint) {
i++;
asmLines.splice(i, 0, extraHint);