mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-05 22:38:44 +00:00
sm parser impl start
This commit is contained in:
parent
b1ab8ee4b3
commit
c5dfe649e0
1 changed files with 125 additions and 1 deletions
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <charconv>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
std::vector<SMInstr> parse_sm(std::istream &in) {
|
||||
std::vector<SMInstr> result;
|
||||
|
|
@ -33,4 +35,126 @@ parse(std::string::iterator begin, std::string::iterator end) {
|
|||
// TODO
|
||||
}
|
||||
|
||||
std::optional<SMInstr> parse_sm(const std::string &line) {}
|
||||
std::string substr_to(const std::string &line, size_t &pos, char to) {
|
||||
auto offset = line.find(pos, to);
|
||||
|
||||
if (offset == std::string::npos) {
|
||||
return "";
|
||||
};
|
||||
|
||||
std::string result = line.substr(pos, offset);
|
||||
pos += offset + 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct SMInstrBuilder {
|
||||
public:
|
||||
SMInstrBuilder(SMInstr instr) : instr(instr), args_pushed(0) {}
|
||||
|
||||
SMInstr build() {
|
||||
// TODO: check for all arps
|
||||
return instr;
|
||||
}
|
||||
|
||||
// TODO
|
||||
void push_arg(std::string &&value) {}
|
||||
void push_arg(bool value) {}
|
||||
void push_arg(int value) {}
|
||||
void push_arg(ValT value) {}
|
||||
void push_arg(Patt value) {}
|
||||
|
||||
private:
|
||||
SMInstr instr;
|
||||
size_t args_pushed = 0;
|
||||
}
|
||||
|
||||
std::optional<SMInstr>
|
||||
parse_sm(const std::string &line) {
|
||||
std::unordered_map<std::string, SMInstr> to_instr = {
|
||||
{"BINOP", SMInstr{SMInstr::BINOP{}}},
|
||||
{"CONST", SMInstr{SMInstr::CONST{}}},
|
||||
{"STRING", SMInstr{SMInstr::STRING{}}},
|
||||
{"SEXP", SMInstr{SMInstr::SEXP{}}},
|
||||
{"LD", SMInstr{SMInstr::LD{ValT::Global{}}}}, // NOTE: as default
|
||||
{"LDA", SMInstr{SMInstr::LDA{ValT::Global{}}}}, // NOTE: as default
|
||||
{"ST", SMInstr{SMInstr::ST{ValT::Global{}}}}, // NOTE: as default
|
||||
{"STI", SMInstr{SMInstr::STI{}}},
|
||||
{"STA", SMInstr{SMInstr::STA{}}},
|
||||
{"ELEM", SMInstr{SMInstr::ELEM{}}},
|
||||
{"LABEL", SMInstr{SMInstr::LABEL{}}},
|
||||
{"FLABEL", SMInstr{SMInstr::FLABEL{}}},
|
||||
{"SLABEL", SMInstr{SMInstr::SLABEL{}}},
|
||||
{"JMP", SMInstr{SMInstr::JMP{}}},
|
||||
{"CJMP", SMInstr{SMInstr::CJMP{}}},
|
||||
{"BEGIN", SMInstr{SMInstr::BEGIN{}}},
|
||||
{"END", SMInstr{SMInstr::END{}}},
|
||||
{"CLOSURE", SMInstr{SMInstr::CLOSURE{}}},
|
||||
{"CALLC", SMInstr{SMInstr::CALLC{}}},
|
||||
{"CALL", SMInstr{SMInstr::CALL{}}},
|
||||
{"RET", SMInstr{SMInstr::RET{}}},
|
||||
{"DROP", SMInstr{SMInstr::DROP{}}},
|
||||
{"DUP", SMInstr{SMInstr::DUP{}}},
|
||||
{"SWAP", SMInstr{SMInstr::SWAP{}}},
|
||||
{"TAG", SMInstr{SMInstr::TAG{}}},
|
||||
{"ARRAY", SMInstr{SMInstr::ARRAY{}}},
|
||||
{"PATT", SMInstr{SMInstr::PATT{}}},
|
||||
{"FAIL", SMInstr{SMInstr::FAIL{}}},
|
||||
{"EXTERN", SMInstr{SMInstr::EXTERN{}}},
|
||||
{"PUBLIC", SMInstr{SMInstr::PUBLIC{}}},
|
||||
{"IMPORT", SMInstr{SMInstr::IMPORT{}}},
|
||||
{"LINE", SMInstr{SMInstr::LINE{}}},
|
||||
};
|
||||
|
||||
char ch; // NOTE: for helpers
|
||||
|
||||
size_t pos = 0;
|
||||
std::string cmd = substr_to(line, pos, ' ');
|
||||
|
||||
auto instr_it = to_instr.find(cmd);
|
||||
if (instr_it == to_instr.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
SMInstrBuilder instr{instr_it->second};
|
||||
|
||||
// no args case
|
||||
if (pos == line.size()) {
|
||||
return instr.build();
|
||||
}
|
||||
|
||||
if (std::string space = substr_to(line, pos, '('); space != " ") {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool was_last_arg = false;
|
||||
while (!was_last_arg) {
|
||||
std::string arg = substr_to(line, pos, '(');
|
||||
++pos;
|
||||
|
||||
if (arg.empty()) {
|
||||
arg = line.substr(pos);
|
||||
arg.pop_back(); // ')'
|
||||
was_last_arg = true;
|
||||
}
|
||||
|
||||
if (arg.front() == '"') {
|
||||
instr.push_arg(arg.substr(1, arg.size() - 2));
|
||||
} else if (arg == "true") {
|
||||
instr.push_arg(true);
|
||||
} else if (arg == "false") {
|
||||
instr.push_arg(false);
|
||||
} else if () { // TODO: Local, Global, Arg
|
||||
} else if () { // TODO: BEGIN vectors, etc
|
||||
} else if () { // TODO: PATT patterns
|
||||
} else if () { // TODO: CLUSURE vector
|
||||
} else if (int n = 0; std::from_chars(line.data() + pos,
|
||||
line.data() + pos + line.size(), n)
|
||||
.ec == std::errc{}) {
|
||||
instr.push_arg(n);
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
return instr.build();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue