parser: allow immediate values to end with colon
This is funky syntax, but it doesn't hurt the accuracy of a parser. Some people might prefer this to stylize references to labels.
This commit is contained in:
parent
7c9ceed58a
commit
a1574d69f8
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,3 +4,5 @@ scu-dsp-asm
|
|||||||
*.gch
|
*.gch
|
||||||
*.d
|
*.d
|
||||||
test/*.s
|
test/*.s
|
||||||
|
test/*.txt
|
||||||
|
*.bin
|
8
Makefile
8
Makefile
@ -15,18 +15,20 @@ SRC += stmt_string.cpp
|
|||||||
OBJ = $(patsubst %.cpp,%.o,$(SRC))
|
OBJ = $(patsubst %.cpp,%.o,$(SRC))
|
||||||
DEP = $(patsubst %.cpp,%.d,$(SRC))
|
DEP = $(patsubst %.cpp,%.d,$(SRC))
|
||||||
|
|
||||||
all: scu-dsp-asm
|
MAIN = scu-dsp-asm
|
||||||
|
|
||||||
|
all: $(MAIN)
|
||||||
|
|
||||||
-include $(DEP)
|
-include $(DEP)
|
||||||
|
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(CXX) $(CXXFLAGS) -MMD -MF $(basename $<).d -c $< -o $@
|
$(CXX) $(CXXFLAGS) -MMD -MF $(basename $<).d -c $< -o $@
|
||||||
|
|
||||||
scu-dsp-asm: $(OBJ)
|
$(MAIN): $(OBJ)
|
||||||
$(CXX) $(STATIC) $(LDFLAGS) $^ -o $@
|
$(CXX) $(STATIC) $(LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *.d *.gch main
|
rm -f *.o *.d *.gch $(MAIN)
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.INTERMEDIATE:
|
.INTERMEDIATE:
|
||||||
|
26
parser.cpp
26
parser.cpp
@ -70,6 +70,14 @@ token_t parser_t::consume(enum token_t::type_t token_type, const std::string err
|
|||||||
throw error(peek(), error_message);
|
throw error(peek(), error_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_t * parser_t::immediate()
|
||||||
|
{
|
||||||
|
match(hash); // optionally consume a hash
|
||||||
|
expr_t * expr = expression();
|
||||||
|
match(colon); // optionally consume a colon
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
expr_t * parser_t::expression()
|
expr_t * parser_t::expression()
|
||||||
{
|
{
|
||||||
return term();
|
return term();
|
||||||
@ -272,8 +280,7 @@ std::optional<op::op_t *> parser_t::xyd1_bus()
|
|||||||
else
|
else
|
||||||
throw error(peek(), "expected x-bus, y-bus, or d-bus destination operand");
|
throw error(peek(), "expected x-bus, y-bus, or d-bus destination operand");
|
||||||
} else {
|
} else {
|
||||||
match(hash); // optionally consume a hash
|
uimm_t<8> imm = uimm_t<8>(peek(), immediate());
|
||||||
uimm_t<8> imm = uimm_t<8>(peek(), expression());
|
|
||||||
consume(comma, "expected `,`");
|
consume(comma, "expected `,`");
|
||||||
if (auto dest_o = d1_dest())
|
if (auto dest_o = d1_dest())
|
||||||
return {new op::mov_imm_d1_t(imm, *dest_o)};
|
return {new op::mov_imm_d1_t(imm, *dest_o)};
|
||||||
@ -362,8 +369,7 @@ std::optional<stmt_t *> parser_t::load()
|
|||||||
{
|
{
|
||||||
if (match(_mvi)) {
|
if (match(_mvi)) {
|
||||||
const token_t& expr_token = peek();
|
const token_t& expr_token = peek();
|
||||||
match(hash); // optionally consume a hash
|
expr_t * expr = immediate();
|
||||||
expr_t * expr = expression();
|
|
||||||
consume(comma, "expected `,`");
|
consume(comma, "expected `,`");
|
||||||
load::dest_t dest = parser_t::load_dest();
|
load::dest_t dest = parser_t::load_dest();
|
||||||
if (match(comma)) {
|
if (match(comma)) {
|
||||||
@ -508,8 +514,7 @@ std::optional<stmt_t *> parser_t::dma()
|
|||||||
if (auto length_ram_o = dma_length_ram()) {
|
if (auto length_ram_o = dma_length_ram()) {
|
||||||
return {new dma::d0_dst_ram_t(hold, add, dst, *length_ram_o)};
|
return {new dma::d0_dst_ram_t(hold, add, dst, *length_ram_o)};
|
||||||
} else {
|
} else {
|
||||||
match(hash); // optionally consume a hash
|
uimm_t<8> imm = uimm_t<8>(peek(), immediate());
|
||||||
uimm_t<8> imm = uimm_t<8>(peek(), expression());
|
|
||||||
return {new dma::d0_dst_imm_t(hold, add, dst, imm)};
|
return {new dma::d0_dst_imm_t(hold, add, dst, imm)};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -520,8 +525,7 @@ std::optional<stmt_t *> parser_t::dma()
|
|||||||
if (auto length_ram_o = dma_length_ram()) {
|
if (auto length_ram_o = dma_length_ram()) {
|
||||||
return {new dma::src_d0_ram_t(hold, add, src, *length_ram_o)};
|
return {new dma::src_d0_ram_t(hold, add, src, *length_ram_o)};
|
||||||
} else {
|
} else {
|
||||||
match(hash); // optionally consume a hash
|
uimm_t<8> imm = uimm_t<8>(peek(), immediate());
|
||||||
uimm_t<8> imm = uimm_t<8>(peek(), expression());
|
|
||||||
return {new dma::src_d0_imm_t(hold, add, src, imm)};
|
return {new dma::src_d0_imm_t(hold, add, src, imm)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -551,12 +555,10 @@ std::optional<stmt_t *> parser_t::jump()
|
|||||||
if (match(_jmp)) {
|
if (match(_jmp)) {
|
||||||
if (auto cond_o = jump_cond()) {
|
if (auto cond_o = jump_cond()) {
|
||||||
consume(comma, "expected `,` after jump condition");
|
consume(comma, "expected `,` after jump condition");
|
||||||
match(hash); // optionally consume a hash
|
uimm_t<8> imm = uimm_t<8>(peek(), immediate());
|
||||||
uimm_t<8> imm = uimm_t<8>(peek(), expression());
|
|
||||||
return {new jump::jmp_cond_t(*cond_o, imm)};
|
return {new jump::jmp_cond_t(*cond_o, imm)};
|
||||||
} else {
|
} else {
|
||||||
match(hash); // optionally consume a hash
|
uimm_t<8> imm = uimm_t<8>(peek(), immediate());
|
||||||
uimm_t<8> imm = uimm_t<8>(peek(), expression());
|
|
||||||
return {new jump::jmp_t(imm)};
|
return {new jump::jmp_t(imm)};
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -38,6 +38,7 @@ struct parser_t
|
|||||||
template <typename... Targs>
|
template <typename... Targs>
|
||||||
bool match(enum token_t::type_t token_type, Targs... args);
|
bool match(enum token_t::type_t token_type, Targs... args);
|
||||||
token_t consume(enum token_t::type_t token_type, const std::string error_message);
|
token_t consume(enum token_t::type_t token_type, const std::string error_message);
|
||||||
|
expr_t * immediate();
|
||||||
|
|
||||||
expr_t * expression();
|
expr_t * expression();
|
||||||
expr_t * term();
|
expr_t * term();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user