diff options
author | Patrick Quist <partouf@gmail.com> | 2021-09-13 20:22:27 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-13 20:22:27 +0200 |
commit | bc6757ae94dbc46fa1243f3277de2262794d5a75 (patch) | |
tree | d264a83fea30a6b189def084c0d422814b814de3 /lib/compilers/pascal.js | |
parent | 3d1a6a672066d5d2b93255ffb7e39a1293bb227c (diff) | |
download | compiler-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.js | 119 |
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); |