mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-20 14:29:16 +00:00
server: updated parsing, flags
This commit is contained in:
parent
d31a8c4efe
commit
c6345ec728
@ -695,3 +695,9 @@ export function coerceToArray<T>(arrobj: any) : T[] {
|
|||||||
else if (typeof arrobj === 'object') return Array.from(Object.values(arrobj))
|
else if (typeof arrobj === 'object') return Array.from(Object.values(arrobj))
|
||||||
else throw new Error(`Expected array or object, got "${arrobj}"`);
|
else throw new Error(`Expected array or object, got "${arrobj}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function replaceAll(s:string, search:string, replace:string) : string {
|
||||||
|
if (s == '') return '';
|
||||||
|
if (search == '') return s;
|
||||||
|
return s.split(search).join(replace);
|
||||||
|
}
|
||||||
|
@ -64,6 +64,7 @@ export class SourceEditor implements ProjectView {
|
|||||||
errorwidgets = [];
|
errorwidgets = [];
|
||||||
errormarks = [];
|
errormarks = [];
|
||||||
inspectWidget;
|
inspectWidget;
|
||||||
|
refreshDelayMsec = 300;
|
||||||
|
|
||||||
createDiv(parent:HTMLElement) {
|
createDiv(parent:HTMLElement) {
|
||||||
var div = document.createElement('div');
|
var div = document.createElement('div');
|
||||||
@ -77,6 +78,9 @@ export class SourceEditor implements ProjectView {
|
|||||||
this.editor.setSelection({line:0,ch:0}, {line:0,ch:0}, {scroll:true}); // move cursor to start
|
this.editor.setSelection({line:0,ch:0}, {line:0,ch:0}, {scroll:true}); // move cursor to start
|
||||||
}
|
}
|
||||||
this.setupEditor();
|
this.setupEditor();
|
||||||
|
if (current_project.getToolForFilename(this.path).startsWith("remote:")) {
|
||||||
|
this.refreshDelayMsec = 1000; // remote URLs get slower refresh
|
||||||
|
}
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +118,7 @@ export class SourceEditor implements ProjectView {
|
|||||||
clearTimeout(this.updateTimer);
|
clearTimeout(this.updateTimer);
|
||||||
this.updateTimer = setTimeout( () => {
|
this.updateTimer = setTimeout( () => {
|
||||||
current_project.updateFile(this.path, this.editor.getValue());
|
current_project.updateFile(this.path, this.editor.getValue());
|
||||||
}, 300);
|
}, this.refreshDelayMsec);
|
||||||
if (this.markHighlight) {
|
if (this.markHighlight) {
|
||||||
this.markHighlight.clear();
|
this.markHighlight.clear();
|
||||||
this.markHighlight = null;
|
this.markHighlight = null;
|
||||||
|
@ -58,6 +58,7 @@ const VCS_PRESETS = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
function getToolForFilename_vcs(fn: string) {
|
function getToolForFilename_vcs(fn: string) {
|
||||||
|
if (fn.endsWith("-llvm.c")) return "remote:llvm-mos";
|
||||||
if (fn.endsWith(".wiz")) return "wiz";
|
if (fn.endsWith(".wiz")) return "wiz";
|
||||||
if (fn.endsWith(".bb") || fn.endsWith(".bas")) return "bataribasic";
|
if (fn.endsWith(".bb") || fn.endsWith(".bas")) return "bataribasic";
|
||||||
if (fn.endsWith(".ca65")) return "ca65";
|
if (fn.endsWith(".ca65")) return "ca65";
|
||||||
|
@ -3,15 +3,15 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { spawn } from 'child_process';
|
import { spawn } from 'child_process';
|
||||||
import { CodeListingMap, WorkerBuildStep, WorkerError, WorkerErrorResult, WorkerFileUpdate, WorkerResult, isOutputResult } from '../../common/workertypes';
|
import { CodeListingMap, WorkerBuildStep, WorkerError, WorkerErrorResult, WorkerFileUpdate, WorkerResult, isOutputResult } from '../../common/workertypes';
|
||||||
import { getBasePlatform, getRootBasePlatform } from '../../common/util';
|
import { getBasePlatform, getRootBasePlatform, replaceAll } from '../../common/util';
|
||||||
import { BuildStep, makeErrorMatcher } from '../workermain';
|
import { BuildStep, makeErrorMatcher } from '../workermain';
|
||||||
import { parseObjDumpListing, parseObjDumpSymbolTable } from './clang';
|
import { parseObjDump } from './clang';
|
||||||
|
|
||||||
|
|
||||||
const LLVM_MOS_TOOL: ServerBuildTool = {
|
const LLVM_MOS_TOOL: ServerBuildTool = {
|
||||||
name: 'llvm-mos',
|
name: 'llvm-mos',
|
||||||
version: '',
|
version: '',
|
||||||
extensions: ['.c', '.cpp', '.s'],
|
extensions: ['.c', '.cpp', '.s', '.S', '.C'],
|
||||||
archs: ['6502'],
|
archs: ['6502'],
|
||||||
platforms: ['atari8', 'c64', 'nes', 'pce', 'vcs'],
|
platforms: ['atari8', 'c64', 'nes', 'pce', 'vcs'],
|
||||||
platform_configs: {
|
platform_configs: {
|
||||||
@ -27,11 +27,9 @@ const LLVM_MOS_TOOL: ServerBuildTool = {
|
|||||||
},
|
},
|
||||||
c64: {
|
c64: {
|
||||||
command: 'mos-c64-clang',
|
command: 'mos-c64-clang',
|
||||||
libargs: ['-D', '__C64__']
|
|
||||||
},
|
},
|
||||||
atari8: {
|
atari8: {
|
||||||
command: 'mos-atari8-clang',
|
command: 'mos-atari8-clang',
|
||||||
libargs: ['-D', '__ATARI__']
|
|
||||||
},
|
},
|
||||||
nes: {
|
nes: {
|
||||||
command: 'mos-nes-nrom-clang', // TODO
|
command: 'mos-nes-nrom-clang', // TODO
|
||||||
@ -39,7 +37,9 @@ const LLVM_MOS_TOOL: ServerBuildTool = {
|
|||||||
},
|
},
|
||||||
pce: {
|
pce: {
|
||||||
command: 'mos-pce-clang', // TODO
|
command: 'mos-pce-clang', // TODO
|
||||||
libargs: ['-D', '__PCE__']
|
},
|
||||||
|
vcs: {
|
||||||
|
command: 'mos-atari2600-3e-clang', // TODO
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,6 +175,10 @@ export class ServerBuildEnv {
|
|||||||
resolve(this.processOutput(step));
|
resolve(this.processOutput(step));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
errorData = replaceAll(errorData, this.sessionDir, '');
|
||||||
|
errorData = replaceAll(errorData, this.rootdir, '');
|
||||||
|
// remove folder paths
|
||||||
|
errorData = errorData.replace(/(\/var\/folders\/.+?\/).+?:/g, '');
|
||||||
let errorResult = await this.processErrors(step, errorData);
|
let errorResult = await this.processErrors(step, errorData);
|
||||||
if (errorResult.errors.length === 0) {
|
if (errorResult.errors.length === 0) {
|
||||||
errorResult.errors.push({ line: 0, msg: `Build failed.\n\n${errorData}` });
|
errorResult.errors.push({ line: 0, msg: `Build failed.\n\n${errorData}` });
|
||||||
@ -203,10 +207,9 @@ export class ServerBuildEnv {
|
|||||||
|
|
||||||
async processDebugInfo(step: WorkerBuildStep): Promise<WorkerResult> {
|
async processDebugInfo(step: WorkerBuildStep): Promise<WorkerResult> {
|
||||||
let dbgfile = path.join(this.sessionDir, 'debug.out');
|
let dbgfile = path.join(this.sessionDir, 'debug.out');
|
||||||
let dbglist = await fs.promises.readFile(dbgfile);
|
let dbglist = (await fs.promises.readFile(dbgfile)).toString();
|
||||||
let listings = parseObjDumpListing(dbglist.toString());
|
let { listings, symbolmap, segments } = parseObjDump(dbglist);
|
||||||
let symbolmap = parseObjDumpSymbolTable(dbglist.toString());
|
return { output: [], listings, symbolmap, segments };
|
||||||
return { output: [], listings, symbolmap };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async compileAndLink(step: WorkerBuildStep, updates: WorkerFileUpdate[]): Promise<WorkerResult> {
|
async compileAndLink(step: WorkerBuildStep, updates: WorkerFileUpdate[]): Promise<WorkerResult> {
|
||||||
|
@ -1,27 +1,37 @@
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { CodeListing, CodeListingMap } from "../../common/workertypes";
|
import { CodeListing, CodeListingMap, Segment } from "../../common/workertypes";
|
||||||
|
|
||||||
export function parseObjDumpSymbolTable(symbolTable) {
|
export function parseObjDump(lst: string) {
|
||||||
const lines = symbolTable.split('\n');
|
// parse symbol map
|
||||||
const result = {};
|
const lines = lst.split('\n');
|
||||||
|
const symbolmap = {};
|
||||||
|
const segments : Segment[] = [];
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
const line = lines[i].trim();
|
const line = lines[i].trim();
|
||||||
if (line.startsWith('00')) {
|
if (line.startsWith("Disassembly")) break;
|
||||||
|
if (line.startsWith('0')) {
|
||||||
const parts = line.split(/\s+/);
|
const parts = line.split(/\s+/);
|
||||||
if (parts.length < 5) continue;
|
if (parts.length < 5) continue;
|
||||||
const symbol = parts[parts.length-1];
|
const symbol = parts[parts.length-1];
|
||||||
const address = parseInt(parts[0], 16);
|
const address = parseInt(parts[0], 16) & 0xffff; // TODO: 32-bit addresses
|
||||||
result[symbol] = address;
|
symbolmap[symbol] = address;
|
||||||
|
// is it a segment?
|
||||||
|
if (symbol.startsWith('__')) {
|
||||||
|
if (symbol.endsWith('_start')) {
|
||||||
|
let name = symbol.substring(2, symbol.length - 6);
|
||||||
|
let type = parts[2] == '.text' ? 'rom' : 'ram';
|
||||||
|
segments.push({ name, start: address, size: 0, type })
|
||||||
|
} else if (symbol.endsWith('_size')) {
|
||||||
|
let name = symbol.substring(2, symbol.length - 5);
|
||||||
|
let seg = segments.find(s => s.name === name);
|
||||||
|
if (seg) seg.size = address;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
// parse listings
|
||||||
}
|
const listings: CodeListingMap = {};
|
||||||
|
|
||||||
export function parseObjDumpListing(lst: string): CodeListingMap {
|
|
||||||
const lines = lst.split('\n');
|
|
||||||
const result: CodeListingMap = {};
|
|
||||||
var lastListing : CodeListing = null;
|
var lastListing : CodeListing = null;
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
const line = lines[i].trim();
|
const line = lines[i].trim();
|
||||||
if (line.startsWith(';')) {
|
if (line.startsWith(';')) {
|
||||||
@ -32,18 +42,18 @@ export function parseObjDumpListing(lst: string): CodeListingMap {
|
|||||||
const file = path.basename(fileParts[0].trim()).split('.')[0] + '.lst';
|
const file = path.basename(fileParts[0].trim()).split('.')[0] + '.lst';
|
||||||
const lineNumber = parseInt(fileParts[1], 10);
|
const lineNumber = parseInt(fileParts[1], 10);
|
||||||
if (lineNumber > 0) {
|
if (lineNumber > 0) {
|
||||||
if (!result[file]) result[file] = { lines: [], text: lst };
|
if (!listings[file]) listings[file] = { lines: [], text: lst };
|
||||||
lastListing = result[file];
|
lastListing = listings[file];
|
||||||
lastListing.lines.push({ line: lineNumber, offset: null });
|
lastListing.lines.push({ line: lineNumber, offset: null });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (lastListing && line.match(/^\s*[A-F0-9]+:.+/i)) {
|
} else if (lastListing && line.match(/^\s*[A-F0-9]+:.+/i)) {
|
||||||
const offsetIndex = line.indexOf(':');
|
const offsetIndex = line.indexOf(':');
|
||||||
if (offsetIndex !== -1) {
|
if (offsetIndex !== -1) {
|
||||||
const offset = parseInt(line.substring(0, offsetIndex).trim(), 16);
|
const offset = parseInt(line.substring(0, offsetIndex).trim(), 16) & 0xffff; // TODO: 32-bit addresses;
|
||||||
lastListing.lines[lastListing.lines.length - 1].offset = offset;
|
lastListing.lines[lastListing.lines.length - 1].offset = offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return { listings, symbolmap, segments };
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user