diff --git a/doc/compilers.txt b/doc/compilers.txt index 5009707a..46724ae1 100644 --- a/doc/compilers.txt +++ b/doc/compilers.txt @@ -33,6 +33,13 @@ osXdk - A fork of the Oric SDK. The C compiler has a weird design which emits bytecode and then uses a C preprocessor to expand the macros into 6502 assembler. +gcc6809 - need to check this out + +SmallerC - https://github.com/alexfru/SmallerC + + +OTHER COMPILERS + PLASMA - Language + VM, sort of like SWEET16 meets Java. Simple, concise code base. Pretty fast too, in the same ballpark as CC65. Focused on the Apple I/II/III family. @@ -55,13 +62,6 @@ machines. https://github.com/EtchedPixels/FUZIX/wiki -gcc6809 - need to check this out - -SmallerC - https://github.com/alexfru/SmallerC - - -OTHER COMPILERS - Java Grinder - Compile Java bytecode to microcontroller assembly. Currently supporting MSP430, dsPIC, 6502/6510, 68000, MIPS, TMS9900, and Z80 with platforms that include Commodore 64, Sega Genesis, Atari 2600, Apple IIgs, diff --git a/index.html b/index.html index d6e30564..7f19b164 100644 --- a/index.html +++ b/index.html @@ -234,6 +234,7 @@ ga('send', 'pageview'); + diff --git a/src/project.js b/src/project.js new file mode 100644 index 00000000..9275e83f --- /dev/null +++ b/src/project.js @@ -0,0 +1,171 @@ +"use strict"; + +function SourceFile(lines, text) { + lines = lines || []; + this.lines = lines; + this.text = text; + this.offset2line = {}; + this.line2offset = {}; + for (var info of lines) { + if (info.offset >= 0) { + this.offset2line[info.offset] = info.line; + this.line2offset[info.line] = info.offset; + } + } + this.findLineForOffset = function(PC) { + if (this.offset2line) { + for (var i=0; i<16; i++) { + var line = this.offset2line[PC]; + if (line >= 0) { + return line; + } + PC--; + } + } + return 0; + } + this.lineCount = function() { return this.line2offset.length; } +} + +function CodeProject(worker, platform_id, platform, store) { + var self = this; + + self.callbackResendFiles = function() { }; // TODO? + self.callbackBuildResult = function(result) { }; + self.callbackBuildStatus = function(busy) { }; + + var pendingWorkerMessages = 0; + + var tools_preloaded = {}; + function preloadWorker(path) { + var tool = platform.getToolForFilename(path); + if (tool && !tools_preloaded[tool]) { + worker.postMessage({preload:tool, platform:platform_id}); + tools_preloaded[tool] = true; + } + } + + self.loadFiles = function(filenames, callback) { + var result = []; + function loadNext() { + var fn = filenames.shift(); + if (!fn) { + callback(null, result); // TODO? + } else { + store.getItem(fn, function(err, value) { + if (err) { + callback(err); + } else if (value) { + result.push({ + path:fn, + data:value + }); + loadNext(); + } else { + var webpath = "presets/" + platform_id + "/" + fn; + if (platform_id == 'vcs' && webpath.indexOf('.') <= 0) + webpath += ".a"; // legacy stuff + $.get( webpath, function( text ) { + console.log("GET",webpath,text.length,'bytes'); + result.push({ + path:fn, + data:text + }); + loadNext(); + }, 'text') + .fail(function() { + callback("Could not load preset " + fn); + }); + } + }); + } + } + loadNext(); // load first file + } + + // TODO: merge with loadFiles() + function loadFileDependencies(text, callback) { + var filenames = []; + if (platform_id == 'verilog') { + var re = /^(`include|[.]include)\s+"(.+?)"/gm; + var m; + while (m = re.exec(text)) { + filenames.push(m[2]); + } + } + var result = []; + function loadNextDependency() { + var fn = filenames.shift(); + if (!fn) { + callback(result); + } else { + store.getItem(fn, function(err, value) { + result.push({ + filename:fn, + prefix:platform_id, + text:value // might be null, that's ok + }); + loadNextDependency(); + }); + } + } + loadNextDependency(); // load first dependency + } + + function okToSend() { + return pendingWorkerMessages++ == 0; + } + + function updateFileInStore(path, text) { + // protect against accidential whole-file deletion + if (text.trim().length) { + // TODO? (originalFileID != path || text != originalText)) { + store.setItem(path, text); + } + } + + self.updateFile = function(path, text, isBinary) { + updateFileInStore(path, text); // TODO: isBinary + preloadWorker(path); + if (okToSend()) { + self.callbackBuildStatus(true); + loadFileDependencies(text, function(depends) { + worker.postMessage({ + code:text, + dependencies:depends, + platform:platform_id, + tool:platform.getToolForFilename(path) + }); + }); + } + }; + + function processBuildResult(data) { + if (data.listings) { + for (var lstname in data.listings) { + var lst = data.listings[lstname]; + if (lst.lines) + lst.sourcefile = new SourceFile(lst.lines); + if (lst.asmlines) + lst.assemblyfile = new SourceFile(lst.asmlines, lst.text); + } + } + } + + worker.onmessage = function(e) { + if (pendingWorkerMessages > 1) { + self.callbackResendFiles(); // TODO: we should handle this internally + pendingWorkerMessages = 0; + } else { + pendingWorkerMessages = 0; + } + self.callbackBuildStatus(false); + if (e.data && !e.data.unchanged) { + processBuildResult(e.data); + self.callbackBuildResult(e.data); + } + }; + + // TODO: parse output, listings, files, etc +} + diff --git a/src/ui.js b/src/ui.js index c2883a03..14cadadf 100644 --- a/src/ui.js +++ b/src/ui.js @@ -37,177 +37,9 @@ var platform; // platform object var toolbar = $("#controls_top"); -var SourceFile = function(lines, text) { - lines = lines || []; - this.lines = lines; - this.text = text; - this.offset2line = {}; - this.line2offset = {}; - for (var info of lines) { - if (info.offset >= 0) { - this.offset2line[info.offset] = info.line; - this.line2offset[info.line] = info.offset; - } - } - this.findLineForOffset = function(PC) { - if (this.offset2line) { - for (var i=0; i<16; i++) { - var line = this.offset2line[PC]; - if (line >= 0) { - return line; - } - PC--; - } - } - return 0; - } - this.lineCount = function() { return this.line2offset.length; } -} - -var CodeProject = function(worker, platform_id, platform, store) { - var self = this; - - self.callbackResendFiles = function() { }; // TODO? - self.callbackBuildResult = function(result) { }; - self.callbackBuildStatus = function(busy) { }; - - var pendingWorkerMessages = 0; - - var tools_preloaded = {}; - function preloadWorker(path) { - var tool = platform.getToolForFilename(path); - if (tool && !tools_preloaded[tool]) { - worker.postMessage({preload:tool, platform:platform_id}); - tools_preloaded[tool] = true; - } - } - - self.loadFiles = function(filenames, callback) { - var result = []; - function loadNext() { - var fn = filenames.shift(); - if (!fn) { - callback(null, result); // TODO? - } else { - store.getItem(fn, function(err, value) { - if (err) { - callback(err); - } else if (value) { - result.push({ - path:fn, - data:value - }); - loadNext(); - } else { - var webpath = "presets/" + platform_id + "/" + fn; - if (platform_id == 'vcs' && webpath.indexOf('.') <= 0) - webpath += ".a"; // legacy stuff - $.get( webpath, function( text ) { - console.log("GET",webpath,text.length,'bytes'); - result.push({ - path:fn, - data:text - }); - loadNext(); - }, 'text') - .fail(function() { - callback("Could not load preset " + fn); - }); - } - }); - } - } - loadNext(); // load first file - } - - // TODO: merge with loadFiles() - function loadFileDependencies(text, callback) { - var filenames = []; - if (platform_id == 'verilog') { - var re = /^(`include|[.]include)\s+"(.+?)"/gm; - var m; - while (m = re.exec(text)) { - filenames.push(m[2]); - } - } - var result = []; - function loadNextDependency() { - var fn = filenames.shift(); - if (!fn) { - callback(result); - } else { - store.getItem(fn, function(err, value) { - result.push({ - filename:fn, - prefix:platform_id, - text:value // might be null, that's ok - }); - loadNextDependency(); - }); - } - } - loadNextDependency(); // load first dependency - } - - function okToSend() { - return pendingWorkerMessages++ == 0; - } - - function updateFileInStore(path, text) { - // protect against accidential whole-file deletion - if (text.trim().length) { - // TODO? (originalFileID != path || text != originalText)) { - store.setItem(path, text); - } - } - - self.updateFile = function(path, text, isBinary) { - updateFileInStore(path, text); // TODO: isBinary - preloadWorker(path); - if (okToSend()) { - self.callbackBuildStatus(true); - loadFileDependencies(text, function(depends) { - worker.postMessage({ - code:text, - dependencies:depends, - platform:platform_id, - tool:platform.getToolForFilename(path) - }); - }); - } - }; - - function processBuildResult(data) { - if (data.listings) { - for (var lstname in data.listings) { - var lst = data.listings[lstname]; - if (lst.lines) - lst.sourcefile = new SourceFile(lst.lines); - if (lst.asmlines) - lst.assemblyfile = new SourceFile(lst.asmlines, lst.text); - } - } - } - - worker.onmessage = function(e) { - if (pendingWorkerMessages > 1) { - self.callbackResendFiles(); // TODO: we should handle this internally - pendingWorkerMessages = 0; - } else { - pendingWorkerMessages = 0; - } - self.callbackBuildStatus(false); - if (e.data && !e.data.unchanged) { - processBuildResult(e.data); - self.callbackBuildResult(e.data); - } - }; - - // TODO: parse output, listings, files, etc -} - var current_project; +// TODO: codemirror multiplex support? var TOOL_TO_SOURCE_STYLE = { 'dasm': '6502', 'acme': '6502', @@ -353,13 +185,14 @@ function loadProject(preset_id) { current_preset_entry = PRESETS[index]; preset_id = current_preset_entry.id; } - // load files from storage or web URLs + // set current file ID current_file_id = preset_id; + // load files from storage or web URLs current_project.loadFiles([preset_id], function(err, result) { if (err) { alert(err); } else if (result && result.length) { - loadCode(result[0].data); + loadCode(result[0].data, preset_id); // TODO } }); } @@ -393,8 +226,7 @@ function _createNewFile(e) { store.setItem(path, result, function(err, result) { if (err) alert(err+""); if (result) { - qs['file'] = "local/" + filename; - gotoNewLocation(); + reloadPresetNamed("local/" + filename); } }); } @@ -1416,8 +1248,7 @@ function loadSharedFile(sharekey) { platform_id = json['platform']; initPlatform(); current_project.updateFile(newid, val.files[filename].content); - qs['file'] = newid; - qs['platform'] = platform_id; + reloadPresetNamed(newid); delete qs['sharekey']; gotoNewLocation(); }).fail(function(err) {