*dies of die*
This commit is contained in:
parent
4e9354a3d9
commit
6f525e2b9d
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
.ccls-cache/
|
||||
.vscode/
|
||||
build/
|
||||
test.x
|
||||
out.asm
|
||||
@ -5,7 +5,7 @@ A short and relatively detailed list of all the basics of XILANG. Also yes, the
|
||||
## Extremly Basic Functions
|
||||
|
||||
* `ret` then a value (can be a numeral or a string) will return that value
|
||||
* `func` then a name (ex: `func main() {}`) allows you to define a new function
|
||||
* `func` then a name (ex: `func main() {};`) allows you to define a new function
|
||||
* `import` and a filename (either in `""` or `<>` depending on if it is a local file in the dir or a file from the include path, similar to C) allows you to import the functions from another file (ex: `import Example.xh`)
|
||||
* `print` then a value will allow to print a character or string to the screen (you can also print any other type of varible)
|
||||
|
||||
@ -21,7 +21,8 @@ you define something by doing the type of var you want to define then a name the
|
||||
|
||||
## Ifs and Loops
|
||||
|
||||
* `if` is pretty simple its just `if x = y {do this}`
|
||||
* `if` is pretty simple its just `if x = y {do this};`
|
||||
* `else` if's best friend! simple as `if x = y {}; else {};`
|
||||
* `loop` is a bit more... dangerous. you can loop... well... basically forever if you were to... forget the value... `loop 100 {print "This"}` or `loop {print "This"}` are both valid ways to use loop, one does the same thing 100 times the other does it until your CPU stops CPUing.
|
||||
* `while` does something while something is true, for example `while x = 1 {print "This"}` or `while x > 1 {print "This"}`
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
;This is a comment
|
||||
|
||||
global _start
|
||||
_start:
|
||||
start:
|
||||
mov rax, 60
|
||||
mov rsi, 0
|
||||
syscall
|
||||
@ -2,4 +2,4 @@
|
||||
|
||||
func main() {
|
||||
ret 0;
|
||||
}
|
||||
};
|
||||
|
||||
94
src/main.cxx
94
src/main.cxx
@ -1,22 +1,108 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#define version "RD-00002"
|
||||
|
||||
#define EXIT_FAILURE 1
|
||||
#define EXIT_SUCCESS 0
|
||||
|
||||
const char *output_filename = "out.asm";
|
||||
|
||||
enum class TokenType {
|
||||
ret,
|
||||
int_lit,
|
||||
semicolon,
|
||||
comment
|
||||
};
|
||||
|
||||
struct Token {
|
||||
TokenType type;
|
||||
std::optional<std::string> value {};
|
||||
};
|
||||
|
||||
std::vector<Token> Tokenize(const std::string& str) {
|
||||
std::vector<Token> Tokens;
|
||||
|
||||
std::string buffer {};
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
char c = str.at(i);
|
||||
if (std::isalpha(c)) {
|
||||
buffer.push_back(c);
|
||||
i++;
|
||||
while (std::isalnum(str.at(i))) {
|
||||
buffer.push_back(str.at(i));
|
||||
i++;
|
||||
}
|
||||
i--;
|
||||
|
||||
if (buffer == "ret") { // return func checkor
|
||||
Tokens.push_back({.type = TokenType::ret});
|
||||
buffer.clear();
|
||||
continue;
|
||||
}
|
||||
} else if (std::isdigit(c)) {
|
||||
buffer.push_back(c);
|
||||
i++;
|
||||
while (std::isdigit(str.at(i))) {
|
||||
buffer.push_back(str.at(i));
|
||||
i++;
|
||||
}
|
||||
i--;
|
||||
Tokens.push_back({.type = TokenType::int_lit, .value = buffer});
|
||||
buffer.clear();
|
||||
}
|
||||
else if (c == ';') { // legit only checks for a semicolon
|
||||
Tokens.push_back({.type = TokenType::semicolon});
|
||||
}
|
||||
else if (std::isspace(c)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return Tokens;
|
||||
}
|
||||
|
||||
std::string Tokens_To_Asm(const std::vector<Token>& Tokens) {
|
||||
std::stringstream output;
|
||||
output << "global _start\nstart:\n";
|
||||
for (int i = 0; i < Tokens.size(); i++) {
|
||||
const Token& Token = Tokens.at(i);
|
||||
if (Token.type == TokenType::ret) {
|
||||
if (i + 1 < Tokens.size() && Tokens.at(i+1).type == TokenType::int_lit) {
|
||||
if (i + 2 < Tokens.size() && Tokens.at(i+2).type == TokenType::semicolon) {
|
||||
output << " mov rax, 60\n";
|
||||
output << " mov rdi, " << Tokens.at(i+1).value.value() << "\n";
|
||||
output << " syscall";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return output.str();
|
||||
}
|
||||
|
||||
int main(int argC, char *argV[]) {
|
||||
if(argC > 2) {
|
||||
std::cerr << "Usage: xic [OPTIONS] [INPUT FILE]\n" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::fstream input(argV[1], std::ios::in);
|
||||
std::string contents;
|
||||
{
|
||||
std::stringstream contents_stream;
|
||||
std::fstream input(argV[1], std::ios::in);
|
||||
contents_stream << input.rdbuf();
|
||||
input.close();
|
||||
|
||||
return 0;
|
||||
contents = contents_stream.str();
|
||||
}
|
||||
|
||||
std::vector<Token> Tokens = Tokenize(contents);
|
||||
|
||||
{
|
||||
std::fstream file(output_filename, std::ios::out);
|
||||
file << Tokens_To_Asm(Tokens);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user