From cc1a4925c2cdfd67837faf04508027cd7cd66a87 Mon Sep 17 00:00:00 2001 From: Robert Lowry Date: Mon, 18 Nov 2024 18:47:36 -0600 Subject: [PATCH] lex colons and accept after line labels (#73) --- lex.go | 2 ++ parser.go | 30 ++++++++++++++++++++++++++++++ parser_test.go | 15 +++++++++++++++ token.go | 1 + 4 files changed, 48 insertions(+) diff --git a/lex.go b/lex.go index 5409053..b86dd62 100644 --- a/lex.go +++ b/lex.go @@ -156,6 +156,8 @@ func lexInput(l *lexer) lexStateFn { fallthrough case '>': return l.emitConsume(token{tokAddressMode, string(l.nextRune)}, lexInput) + case ':': + return l.emitConsume(token{tokColon, ":"}, lexInput) case '\x1a': return l.consume(lexInput) default: diff --git a/parser.go b/parser.go index 11d82c7..0785660 100644 --- a/parser.go +++ b/parser.go @@ -220,6 +220,8 @@ func parseComment(p *parser) parseStateFn { // parseLabels consumes text tokens until an op is read // label text token: parseLabels // op text token: parseOp +// colon: parseColon +// newline / comments: consume // anyting else: nil func parseLabels(p *parser) parseStateFn { if p.nextToken.IsOp() { @@ -229,6 +231,10 @@ func parseLabels(p *parser) parseStateFn { return parseOp } + if p.nextToken.typ == tokColon { + return parseColon + } + _, ok := p.symbols[p.nextToken.val] if ok { p.err = fmt.Errorf("line %d: symbol '%s' redefined", p.line, p.nextToken.val) @@ -251,6 +257,30 @@ func parseLabels(p *parser) parseStateFn { return parseLabels } +// from: parseLabels +// newline or comments: parseColon +// op: parseOp +// anything else: nil +func parseColon(p *parser) parseStateFn { + p.next() + + // just consume newlines and comments for now + if p.nextToken.typ == tokNewline || p.nextToken.typ == tokComment { + p.next() + return parseColon + } + + if p.nextToken.IsOp() { + if p.nextToken.IsPseudoOp() { + return parsePseudoOp + } + return parseOp + } + + p.err = fmt.Errorf("line %d: op expected after colon, got '%s'", p.line, p.nextToken) + return nil +} + // from: parseLabels // comment: parseComment // newline: parseLine diff --git a/parser_test.go b/parser_test.go index b6dfaea..3dcf3c0 100644 --- a/parser_test.go +++ b/parser_test.go @@ -76,6 +76,21 @@ func TestParserPositive(t *testing.T) { newlines: 1, }}, }, + { + input: "a: mov $0, $1 ; comment\n", + output: []sourceLine{{ + line: 1, + labels: []string{"a"}, + typ: lineInstruction, + op: "mov", + amode: "$", + a: []token{{typ: tokNumber, val: "0"}}, + bmode: "$", + b: []token{{typ: tokNumber, val: "1"}}, + comment: "; comment", + newlines: 1, + }}, + }, { input: "mov $ -1, $ 2 + 2\n", output: []sourceLine{{ diff --git a/token.go b/token.go index ab450b6..05ddb2c 100644 --- a/token.go +++ b/token.go @@ -11,6 +11,7 @@ const ( tokNumber // (optionally) signed integer tokExprOp // + - * / % == tokComma + tokColon tokParenL tokParenR tokComment // includes semi-colon, no newline char