diff --git a/6502.lua b/6502.lua index 0734bff..0d15ce1 100644 --- a/6502.lua +++ b/6502.lua @@ -4,6 +4,10 @@ local symbols={} M.symbols=symbols local locations={} M.locations=locations local stats={} M.stats=stats +M.__index = M +symbols.__index = symbols +setmetatable(M, symbols) + local section_current -- cache of last location's last section, for faster access M.link = function() @@ -191,7 +195,6 @@ M.section = function(t) size = size + #instruction.data end self.size = size - -- set start and finish fields of constraints for _,constraint in ipairs(self.constraints) do constraint.start = instructions[constraint.from].offset constraint.finish = instructions[constraint.to].offset diff --git a/asm.l65 b/asm.l65 index 4bde620..c785ec1 100644 --- a/asm.l65 +++ b/asm.l65 @@ -1,3 +1,6 @@ +local g = function(a) return a*3 end +local f = \a(a*3) + dofile "vcs.lua" TIM_OVERSCAN = 50 -- TIM64T, 3200 cycles = ~ 42 scanlines @@ -17,8 +20,33 @@ x:f() lda = 5 if lda < 6 then print('yep') end #pragma syntax6502 on ---@@data samepage byte(1, 2) crosspage byte(3, 4) +--[[ +local function ptr_table(label, ...) + local vals = {...} + section(label .. "_lo") + for _,v in ipairs(vals) do byte_lo(v) end + section(label .. "_hi") + for _,v in ipairs(vals) do byte_hi(v) end +end +]] +--@@message byte(4) "test" byte(0) + +@@data + crosspage + byte(1, 2) byte(3, 4) + end + word(0xf080) byte(16, 3, 4, 5, 6, + 24, 32) + --[[ + word(message) + byte_lo(message) byte_hi(message) + --]] + byte(\(message&0xff), \(message>>8)) + --[[ + +ptr_table("ptrs", message, data, 0) +--]] --section{ "toto", align = 256, offset = 16 } --section{ "toto", org = 0xf100 } --section "waitForIntim" @@ -29,6 +57,15 @@ lda = 5 if lda < 6 then print('yep') end ldx #0xf0 ldx #0b1101 ldy #0xAB - 16 + 0b11011 & 3 | 6 ~ 0xf >> ~3 << 1 // 5 + --[[ + lda data + lda data,5 + lda data,function(final_address) return final_address & 3 end + lda data,\a(a&3) + lda (INTIM,5,x) + lda (INTIM,5),y + -- parse value list, si #list > 1 && list[#list-1] == 'x' ... + ]] samepage lda #0xac diff --git a/asm.lua b/asm.lua index ae46831..957f031 100644 --- a/asm.lua +++ b/asm.lua @@ -1,3 +1,6 @@ +local g = function(a) return a*3 end +local f = function(a) return a*3 end + dofile "vcs.lua" TIM_OVERSCAN = 50 -- TIM64T, 3200 cycles = ~ 42 scanlines @@ -17,28 +20,63 @@ x:f() lda = 5 if lda < 6 then print('yep') end ; ---@@data samepage byte(1, 2) crosspage byte(3, 4) +--[[ +local function ptr_table(label, ...) + local vals = {...} + section(label .. "_lo") + for _,v in ipairs(vals) do byte_lo(v) end + section(label .. "_hi") + for _,v in ipairs(vals) do byte_hi(v) end +end +]] +--@@message byte(4) "test" byte(0) + +section("data") + do crosspage() + byte(1, 2) byte(3, 4) endpage() + end + word(0xf080) byte(16, 3, 4, 5, 6, + 24, 32) + --[[ + word(message) + byte_lo(message) byte_hi(message) + --]] + byte(function() return message&0xff end, function() return message>>8 end) + --[[ + +ptr_table("ptrs", message, data, 0) +--]] --section{ "toto", align = 256, offset = 16 } --section{ "toto", org = 0xf100 } -section "waitForIntim" --alt short syntax when no other option: @@waitForIntim ? +--section "waitForIntim" +section("waitForIntim") --alt short syntax when no other option -- n_{ a=INTIM } ? --lda(INTIM) -- or a=INTIM --bne "waitForIntim" ldx_immediate(0xf0) ldx_immediate(13) ldy_immediate(0xAB - 16 + 27 & 3 | 6 ~ 0xf >> ~3 << 1 // 5) + --[[ + lda data + lda data,5 + lda data,function(final_address) return final_address & 3 end + lda data,\a(a&3) + lda (INTIM,5,x) + lda (INTIM,5),y + -- parse value list, si #list > 1 && list[#list-1] == 'x' ... + ]] do samepage() - lda_immediate(0xac) - lda_immediate(INTIM) - lda_absolute( 0xbeef) - lda_absolute( INTIM) - lda_absolute_nozp( INTIM) - lda_absolute_x( INTIM) - lda_absolute_x( INTIM) - lda_indirect_x(INTIM) - lda_indirect_y(INTIM) endpage() + lda_immediate(0xac) + lda_immediate(INTIM) + lda_absolute( 0xbeef) + lda_absolute( INTIM) + lda_absolute_nozp( INTIM) + lda_absolute_x( INTIM) + lda_absolute_x( INTIM) + lda_indirect_x(INTIM) + lda_indirect_y(INTIM) endpage() end asl_implied() diff --git a/l65.lua b/l65.lua index c9fbf29..da8f689 100644 --- a/l65.lua +++ b/l65.lua @@ -544,6 +544,9 @@ local function LexLua(src) toEmit = {Type = 'Symbol', Data = '@'} end + elseif syntax6502_on and consume('\\') then + toEmit = {Type = 'Symbol', Data = '\\'} + elseif Symbols[c] then get() toEmit = {Type = 'Symbol', Data = c} @@ -813,6 +816,7 @@ local function ParseLua(src) nodePrimExp.Tokens = tokenList -- return true, nodePrimExp + else return false, GenerateError("primary expression expected") end @@ -1038,6 +1042,45 @@ local function ParseLua(src) func.IsLocal = true return true, func + elseif tok:ConsumeSymbol('\\', tokenList) then -- short lambdas \params(expr) + local funcScope = CreateScope(scope) + + local argList = {} + if not tok:ConsumeSymbol('(', tokenList) then while true do + if not tok:Is('Ident') then return false, GenerateError("identifier expected") end + argList[#argList+1] = funcScope:CreateLocal(tok:Get(tokenList).Data) + if tok:ConsumeSymbol('(', tokenList) then break end + if not tok:ConsumeSymbol(',', tokenList) then return false, GenerateError("'(' expected") end + end end + --local st, body = ParseStatementList(funcScope) + local st, body = ParseExpr(funcScope) + if not st then return false, body end + if not tok:ConsumeSymbol(')', tokenList) then return false, GenerateError("')' expected after lambda body") end + + local last_tok = body.Tokens[1] + local last_char,last_line = last_tok.Char,last_tok.Line + local space = { Char=last_char, Line=last_line, Data=' ', Type='Whitespace' } + local ret = { AstType='ReturnStatement', Arguments={body}, TrailingWhite=true, Tokens={ + { Char=last_char, Line=last_line, Print=function() return '' end, LeadingWhite={space}, Type='Keyword', Data='return' } + }} + local statList = { AstType='Statlist', Scope=CreateScope(funcScope), Tokens={}, Body={ret} } + + local tok_first = tokenList[1] + tok_first.Type = 'Keyword' + tok_first.Data = 'function' + tok_first.Print=function() return '' end + + local ntokl = {} + local paren_ix = 2 + math.max(0, #argList*2-1) + table.insert(ntokl, tokenList[1]) + table.insert(ntokl, tokenList[paren_ix]) + for i=2,paren_ix-1 do table.insert(ntokl, tokenList[i]) end + table.insert(ntokl, tokenList[#tokenList]) + table.insert(ntokl, { Char=last_char, Line=last_line, Type='Keyword', Data='end', Print=function() return '' end, LeadingWhite={space} }) + + local func = { AstType='Function', Scope=funcScope, Arguments=argList, Body=statList, VarArg=false, Tokens=ntokl, isLocal=true } + return true, func + else return ParseSuffixedExpr(scope) end @@ -1984,6 +2027,7 @@ local function Format65(ast) elseif statement.AstType == 'ReturnStatement' then appendNextToken( "return" ) + if statement.TrailingWhite then out:appendStr(' ') end for i = 1, #statement.Arguments do formatExpr(statement.Arguments[i]) appendComma( i ~= #statement.Arguments ) diff --git a/vcs.lua b/vcs.lua index fa1d5e4..7fa92e0 100644 --- a/vcs.lua +++ b/vcs.lua @@ -1,6 +1,5 @@ -- set cpu to 6502 cpu = require "6502" -cpu.__index = cpu setmetatable(_ENV, cpu) vcs = { @@ -82,8 +81,5 @@ vcs = { } do local symbols = cpu.symbols - for k,v in pairs(vcs) do - _ENV[k] = v - symbols[k] = v - end + for k,v in pairs(vcs) do symbols[k] = v end end