parser: add assign and label

This commit is contained in:
Zack Buhman 2023-08-20 08:45:16 +00:00
parent 867ee171a5
commit cd0c9c7c8c
10 changed files with 68 additions and 21 deletions

10
ast.cpp
View File

@ -249,4 +249,14 @@ void ast_printer_t::visit(const nop::nop_t * nop) const
parenthesize("nop"); parenthesize("nop");
} }
void ast_printer_t::visit(const assign_t * assign) const
{
parenthesize("assign", assign->name.lexeme, assign->value);
}
void ast_printer_t::visit(const label_t * label) const
{
parenthesize("label", label->name.lexeme);
}
} }

View File

@ -53,6 +53,8 @@ struct ast_printer_t : visitor_t<void>
void visit(const nop::nop_t * nop) const; void visit(const nop::nop_t * nop) const;
void visit(const assign_t * assign) const;
void visit(const label_t * label) const;
void parenthesize(const std::string_view s, const expr_t * a) const; void parenthesize(const std::string_view s, const expr_t * a) const;
void parenthesize(const std::string_view s1, const std::string_view s2, const expr_t * a) const; void parenthesize(const std::string_view s1, const std::string_view s2, const expr_t * a) const;

View File

@ -165,6 +165,7 @@ std::optional<token_t> lexer_t::lex_token()
case '|': return {{pos, bar, lexeme()}}; case '|': return {{pos, bar, lexeme()}};
case '^': return {{pos, carot, lexeme()}}; case '^': return {{pos, carot, lexeme()}};
case '=': return {{pos, equal, lexeme()}}; case '=': return {{pos, equal, lexeme()}};
case ':': return {{pos, colon, lexeme()}};
case '<': case '<':
if (match('<')) return {{pos, left_shift, lexeme()}}; if (match('<')) return {{pos, left_shift, lexeme()}};
break; break;
@ -206,7 +207,7 @@ std::optional<token_t> lexer_t::lex_token()
} else if (alpha_p(c)) { } else if (alpha_p(c)) {
return {_identifier()}; return {_identifier()};
} else { } else {
error(pos.line, pos.col - 1, "Unexpected character."); error(pos.line, pos.col - 1, "unexpected character");
return {}; return {};
} }
break; break;

View File

@ -22,7 +22,7 @@ static void run(std::string source)
lexer_t lexer(buf); lexer_t lexer(buf);
std::vector<token_t> tokens = lexer.lex_tokens(); std::vector<token_t> tokens = lexer.lex_tokens();
parser_t parser(tokens); parser_t parser(tokens);
std::optional<stmt_t *> stmt_o = parser.instruction(); std::optional<stmt_t *> stmt_o = parser.statement();
if (stmt_o) { if (stmt_o) {
dsp::ast_printer_t p(std::cout); dsp::ast_printer_t p(std::cout);
(*stmt_o)->accept(&p); (*stmt_o)->accept(&p);

View File

@ -52,7 +52,7 @@ const token_t& parser_t::advance()
bool parser_t::check(enum token_t::type_t token_type) bool parser_t::check(enum token_t::type_t token_type)
{ {
if (at_end_p()) return false; if (at_end_p() && token_type != eof) return false;
return peek().type == token_type; return peek().type == token_type;
} }
@ -567,17 +567,34 @@ std::optional<stmt_t *> parser_t::instruction()
else return {}; else return {};
} }
std::optional<stmt_t *> parser_t::instruction_statement() std::optional<stmt_t *> parser_t::statement()
{ {
// label if (check(eol)) {
// instruction while (!at_end_p() && check(eol)) advance();
// newline return statement();
} else if (check(eof)) {
return {}; return {};
} } else if (match(identifier)) {
token_t name = previous();
stmt_t * parser_t::statement() if (match(colon)) {
{ return {new label_t(name)};
return nullptr; } else if (match(equal) || match(_equ)) {
expr_t * value = expression();
if (check(eol) || check(eof))
return {new assign_t(name, value)};
else
throw error(peek(), "expected eol or eof after assignment");
} else {
throw error(peek(), "expected assignment or label");
}
} else if (auto ins_o = instruction()) {
if (check(eol) || check(eof))
return ins_o;
else
throw error(peek(), "expected eol or eof after instruction");
} else {
throw error(peek(), "expected statement");
}
} }
} }

View File

@ -64,8 +64,7 @@ struct parser_t
std::optional<stmt_t *> loop(); std::optional<stmt_t *> loop();
std::optional<stmt_t *> end(); std::optional<stmt_t *> end();
std::optional<stmt_t *> instruction(); std::optional<stmt_t *> instruction();
std::optional<stmt_t *> instruction_statement(); std::optional<stmt_t *> statement();
stmt_t * statement();
}; };
} }

View File

@ -258,7 +258,6 @@ struct nop_t : stmt_accept_t<nop_t>
} }
/*
struct assign_t : stmt_accept_t<assign_t> struct assign_t : stmt_accept_t<assign_t>
{ {
assign_t(token_t name, expr_t * value) assign_t(token_t name, expr_t * value)
@ -267,6 +266,13 @@ struct assign_t : stmt_accept_t<assign_t>
const token_t name; const token_t name;
const expr_t * value; const expr_t * value;
}; };
*/
struct label_t : stmt_accept_t<label_t>
{
label_t(token_t name)
: name(name) {}
const token_t name;
};
} // dsp } // dsp

View File

@ -38,13 +38,16 @@ struct token_t {
carot, carot,
left_shift, left_shift,
right_shift, right_shift,
equal,
// literals // literals
identifier, identifier,
string, string,
number, number,
// assign and label
equal,
colon,
// ends // ends
eof, eof,
eol, eol,
@ -91,13 +94,16 @@ struct token_t {
case carot : return os << "CAROT"; case carot : return os << "CAROT";
case left_shift : return os << "LEFT_SHIFT"; case left_shift : return os << "LEFT_SHIFT";
case right_shift : return os << "RIGHT_SHIFT"; case right_shift : return os << "RIGHT_SHIFT";
case equal : return os << "EQUAL";
// literals // literals
case identifier : return os << "IDENTIFIER"; case identifier : return os << "IDENTIFIER";
case string : return os << "STRING"; case string : return os << "STRING";
case number : return os << "NUMBER"; case number : return os << "NUMBER";
// assign and label
case equal : return os << "EQUAL";
case colon : return os << "COLON";
// keywords // keywords
#include "keyword.case_inc" #include "keyword.case_inc"

View File

@ -56,4 +56,7 @@ namespace nop {
struct nop_t; struct nop_t;
} }
struct assign_t;
struct label_t;
} }

View File

@ -43,6 +43,9 @@ struct visitor_t
virtual T visit(const end::endi_t * endi) const = 0; virtual T visit(const end::endi_t * endi) const = 0;
virtual T visit(const nop::nop_t * nop) const = 0; virtual T visit(const nop::nop_t * nop) const = 0;
virtual T visit(const assign_t * assign) const = 0;
virtual T visit(const label_t * label) const = 0;
}; };
} }