diff --git a/parsers/instruction.js b/parsers/instruction.js index 878eba5..3bd2e04 100644 --- a/parsers/instruction.js +++ b/parsers/instruction.js @@ -25,7 +25,7 @@ function instructionName () { function instruction () { return mona.sequence((s) => { const i = s(instructionName()) - const space = s(mona.spaces()) + const space = s(mona.maybe(mona.spaces())) const args = s(mona.maybe(parameters())) // const nl = s(mona.eol()) return mona.value({ diff --git a/parsers/parameters.js b/parsers/parameters.js index 22d146d..9eb2d5b 100644 --- a/parsers/parameters.js +++ b/parsers/parameters.js @@ -1,16 +1,11 @@ const mona = require('mona') function quotedChar () { - return mona.or(mona.noneOf('"'), - mona.and(mona.string('""'), - mona.value('"'))) -} - -function alphanum () { - return mona.join( - mona.value('alphanum'), - mona.string('background3') - ) + return mona.or( + mona.noneOf('"'), + mona.and( + mona.string('""'), + mona.value('"'))) } function bit () { @@ -68,28 +63,39 @@ function address () { ) } -function parameter () { - return mona.collect( - mona.or( - address(), - binary(), - hex(), - string(), - bit(), - alphanum() +// this is the fallthrough parser +function alphanum () { + return mona.join( + mona.value('alphanum'), + mona.and( + mona.not(bit()), + mona.not(address()), + mona.not(binary()), + mona.not(bit()), + mona.not(string()), + mona.text(mona.alphanum()) ) ) } +function parameter () { + return mona.or( + address(), + binary(), + hex(), + string(), + bit(), + alphanum() + ) +} + function parameters () { - return mona.map(a => a.map(b => b[0]), - mona.split( - parameter(), - mona.or( - mona.and(mona.string(','), mona.spaces()), - mona.string(','), - mona.spaces() - ) + return mona.split( + parameter(), + mona.or( + mona.and(mona.string(','), mona.spaces()), + mona.string(','), + mona.spaces() ) ) } diff --git a/test/assembler.js b/test/assembler.js index 5657efd..fc30a2f 100644 --- a/test/assembler.js +++ b/test/assembler.js @@ -8,7 +8,10 @@ tap.test('should parse the basics', (t) => { { directive: '.org', args: [ - '$,C000' + [ + 'address', + 'C000' + ] ] }, { diff --git a/test/instruction.js b/test/instruction.js index e76aa54..f849737 100644 --- a/test/instruction.js +++ b/test/instruction.js @@ -4,7 +4,7 @@ const instructionParser = require('../parsers/instruction') tap.test('will parse an instruction', (t) => { t.plan(1) - t.deepEqual(mona.parse(instructionParser(), 'sei'), { + t.deepEqual(mona.parse(instructionParser(), 'sei\n'), { args: null, instruction: 'sei' }) @@ -12,7 +12,7 @@ tap.test('will parse an instruction', (t) => { tap.test('will parse an instruction with args', (t) => { t.plan(1) - t.deepEqual(mona.parse(instructionParser(), 'stx $2000'), { + t.deepEqual(mona.parse(instructionParser(), 'stx $2000\n'), { args: [ [ 'address', @@ -25,7 +25,7 @@ tap.test('will parse an instruction with args', (t) => { tap.test('will parse an instruction with multiple args', (t) => { t.plan(1) - t.deepEqual(mona.parse(instructionParser(), 'lda background3, x'), { + t.deepEqual(mona.parse(instructionParser(), 'lda background3, x\n'), { args: ['background3', 'x'], instruction: 'lda' }) diff --git a/test/parameters.js b/test/parameters.js index 6fd8f4e..93a4fa3 100644 --- a/test/parameters.js +++ b/test/parameters.js @@ -11,6 +11,21 @@ tap.test('should parse direct memory address param', (t) => { ]) }) +tap.test('should parse alphanum param', (t) => { + t.plan(1) + const input = 'background3' + t.deepEqual(mona.parse(parsers.alphanum(), input), [ + 'alphanum', + 'background3' + ]) +}) + +tap.test('should not parse alphanum param if empty', (t) => { + t.plan(1) + const input = '' + t.notOk(mona.parse(parsers.alphanum(), input)) +}) + tap.test('should parse hex param', (t) => { t.plan(1) const input = '#$FF' @@ -31,13 +46,10 @@ tap.test('should parse binary param', (t) => { tap.test('should parse param', (t) => { t.plan(1) - const input = '#%00000001' t.deepEqual(mona.parse(parsers.parameter(), input), [ - [ - 'binary', - '00000001' - ] + 'binary', + '00000001' ]) })