*dies of die*
This commit is contained in:
parent
4e9354a3d9
commit
6f525e2b9d
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
.ccls-cache/
|
.ccls-cache/
|
||||||
.vscode/
|
.vscode/
|
||||||
build/
|
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
|
## Extremly Basic Functions
|
||||||
|
|
||||||
* `ret` then a value (can be a numeral or a string) will return that value
|
* `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`)
|
* `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)
|
* `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
|
## 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.
|
* `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"}`
|
* `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
|
;This is a comment
|
||||||
|
|
||||||
global _start
|
global _start
|
||||||
_start:
|
start:
|
||||||
mov rax, 60
|
mov rax, 60
|
||||||
mov rsi, 0
|
mov rsi, 0
|
||||||
syscall
|
syscall
|
||||||
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ret 0;
|
ret 0;
|
||||||
}
|
};
|
||||||
|
|||||||
96
src/main.cxx
96
src/main.cxx
@ -1,22 +1,108 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#define version "RD-00002"
|
#define version "RD-00002"
|
||||||
|
|
||||||
#define EXIT_FAILURE 1
|
#define EXIT_FAILURE 1
|
||||||
#define EXIT_SUCCESS 0
|
#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[]) {
|
int main(int argC, char *argV[]) {
|
||||||
if(argC > 2) {
|
if(argC > 2) {
|
||||||
std::cerr << "Usage: xic [OPTIONS] [INPUT FILE]\n" << std::endl;
|
std::cerr << "Usage: xic [OPTIONS] [INPUT FILE]\n" << std::endl;
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::fstream input(argV[1], std::ios::in);
|
std::string contents;
|
||||||
std::stringstream contents_stream;
|
{
|
||||||
contents_stream << input.rdbuf();
|
std::stringstream contents_stream;
|
||||||
input.close();
|
std::fstream input(argV[1], std::ios::in);
|
||||||
|
contents_stream << input.rdbuf();
|
||||||
|
contents = contents_stream.str();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
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