diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bd198c7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +test +xiranda diff --git a/compile.sh b/compile.sh new file mode 100644 index 0000000..6ba82c1 --- /dev/null +++ b/compile.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -xe + +gcc -g -ansi -Wall -Wextra -Wpedantic -Werror -o xiranda xiranda.c + +exit diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..ebd3f38 --- /dev/null +++ b/install.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -xe + +cp xiranda /usr/bin/xiranda + +exit diff --git a/test.asm b/test.asm new file mode 100644 index 0000000..818b87c --- /dev/null +++ b/test.asm @@ -0,0 +1,111 @@ +linux_read_system_call = 0 +linux_write_system_call = 1 +linux_open_system_call = 2 +linux_close_system_call = 3 +linux_exit_system_call = 60 + +standard_input = 0 +standard_output = 1 + +format ELF64 executable 3 + +segment readable executable + +main: + mov [echo_0], text_data ; text); + call echo ; echo ( + + loop_1: + cmp [main_x], 51 + jnb loop_1e + xor rdx, rdx + mov eax, [main_x] + mov ebx, 15 + idiv rbx + cmp edx, 0 + jne n3 + mov [echo_0], fb + call echo + jmp n0 + n3: + xor rdx, rdx + mov eax, [main_x] + mov ebx, 3 + idiv rbx + cmp edx, 0 + jne n1 + mov [echo_0], f + call echo + jmp n0 + n1: + xor rdx, rdx + mov eax, [main_x] + mov ebx, 5 + idiv rbx + cmp edx, 0 + jne n2 + mov [echo_0], b + call echo + jmp n0 + n2: + mov [echo_0], n + call echo + n0: + inc [main_x] + jmp loop_1 + loop_1e: + ; + mov rax, linux_exit_system_call ;
return;; + xor rdi, rdi + syscall + +;~string_length (character * text): + ;~natural length = 0; + ;~loop (* (text + length++)); + ;~return (length);; + +string_length: ; string_length + mov [string_length_length], 0 ; length = 0; + mov rax, [string_length_0] ; text + loop_0: ; loop_0 + cmp byte [rax], 0 ; (* (text + length)) != '\0' + je loop_0e + inc rax ; text + length + inc [string_length_length] ; length++ + jmp loop_0 ; if not go loop_0 + loop_0e: + xor rax, rax + mov eax, [string_length_length] ; return (length); + ret ; ; + +;~echo (character * text): + ;~system (linux_write_system_call, standard_output, text, string_length (text)); + ;~return;; +echo: ; echo ) + mov rax, [echo_0] ; | + mov [string_length_0], rax ; | + call string_length ; | + mov rdx, rax ; | string_length (text) + mov rsi, [echo_0] ; text + mov rdi, standard_output ; standard_output + mov rax, linux_write_system_call ; linux_write_system_call + syscall ; system ( + xor rax, rax ; return;; + ret ; + +segment readable writable + +; variable +string_length_length dd 0 ; natural length = 0; +main_x dd 1 ; integer x = 0; + +; function +echo_0 dq 0 ; character * text +string_length_0 dq 0 ; character * text + +; data +text_data db 'Heyo world!', 10, 0 +fb db 'fizzbuzz', 10, 0 +f db 'fizz', 10, 0 +b db 'buzz', 10, 0 +n db 'number', 10, 0 diff --git a/test.c b/test.c new file mode 100644 index 0000000..a158df3 --- /dev/null +++ b/test.c @@ -0,0 +1,38 @@ +//~#include + +//~int string_length (char * string) { + //~int length = 0; + //~while (* (string + length)) length++; + //~return length; +//~} + +//~void echo (char * string) { + //~write (1, string, string_length (string)); +//~} + +//~int main (void) { + //~echo ("Heyo world!\n"); + //~return (0); +//~} + +extern int z; + +extern int strlen (char * data) { + int l = 0; + while (* (data + l) != 0) l++; + return l; +} + +extern int add (int x, int y) { + z = x + y; + return x; +} + +extern int zod (int x, int y) { + return x % y; +} + +extern int mod (int x, int y) { + x = add (x, y); + return x % y; +} diff --git a/test.x b/test.x new file mode 100644 index 0000000..4e1a003 --- /dev/null +++ b/test.x @@ -0,0 +1,47 @@ +--- Heyo + +type boolean (false, true) + +type character = -128 .. 127; +type integer = -2000000000 .. 2000000000; +type natural % 2000000000; + +type structure: + integer a = 0; + boolean b = 0; + natural c = 0;; + +type system_call ( + linux_read_system_call = 0, + linux_write_system_call = 1, + linux_open_system_call = 2, + linux_close_system_call = 3, + linux_exit_system_call = 60) + +type file_descriptor ( + standard_input = 0, + standard_output = 1) + +main: + x: integer = 1; + loop (x++ < 101): + if ((x % 3 = 0) && (x % 5 = 0)) + echo ("fizzbuzz\n"); + else if (x % 3 = 0): + echo ("fizz\n"); + echo ("and again fizz\n");; + else if (x % 5 = 0) + echo ("buzz\n"); + else: + echo ("fuck formatting...\n"); + echo ("fuck formatting twice...\n");; + return (0);; + +string_length (character * text): + length: natural = 0; + loop (* (text + length++)); + return (length);; + +echo (character * text): + system (linux_write_system_call, standard_output, text, string_length (text)); + return;; diff --git a/xiranda.c b/xiranda.c new file mode 100644 index 0000000..a122710 --- /dev/null +++ b/xiranda.c @@ -0,0 +1,216 @@ +#include + +enum { + core_none, core_word, core_marker, core_string, core_number, + core_symbol +}; + +enum { + word_type, word_loop, word_if, word_else, word_case, + word_return, word_import, word_export, word_define, word_system +}; + +#define STRING_LIMIT (80) +#define NAME_LIMIT (80) + +static int token_count = 0; +static int string_code = 0; +static int number_code = 0; +static int marker_code = 0; +static int symbol_code = 0; + +static int * token_data = null; +static int * token_type = null; +static char * * string_name = null; +static char * * string_data = null; +static int * string_size = null; +static char * * number_name = null; +static int * number_data = null; +static char * * marker_name = null; +static int * marker_type = null; +static char * symbol_data = null; + +#include + +static char * word_list [] = { + "type", "loop", "if", "else", "case", "return", + "import", "export", "define", "system" +}; + +static void add_token (int type, int data) { + token_data = reallocate (token_data, (token_count + 1) * (int) sizeof (* token_data)); + token_type = reallocate (token_type, (token_count + 1) * (int) sizeof (* token_type)); + token_data [token_count] = data; + token_type [token_count] = type; + ++token_count; +} + +static void add_string (char * data, int size) { + string_data = reallocate (string_data, (string_code + 1) * (int) sizeof (* string_data)); + string_size = reallocate (string_size, (string_code + 1) * (int) sizeof (* string_size)); + string_data [string_code] = allocate (STRING_LIMIT * (int) sizeof (* string_data)); + string_copy (string_data [string_code], data); + string_size [string_code] = size; + ++string_code; +} + +static void add_number (int data) { + number_data = reallocate (number_data, (number_code + 1) * (int) sizeof (* number_data)); + number_data [number_code] = data; + ++number_code; +} + +static void add_marker (char * name, int type) { + marker_name = reallocate (marker_name, (marker_code + 1) * (int) sizeof (* marker_name)); + marker_type = reallocate (marker_type, (marker_code + 1) * (int) sizeof (* marker_type)); + marker_name [marker_code] = allocate (NAME_LIMIT * (int) sizeof (* marker_name)); + string_copy (marker_name [marker_code], name); + marker_type [marker_code] = type; + ++marker_code; +} + +static void add_symbol (char data) { + symbol_data = reallocate (symbol_data, (symbol_code + 1) * (int) sizeof (* symbol_data)); + symbol_data [symbol_code] = data; + ++symbol_code; +} + +static void kill (char * data) { + terminal_colour (colour_red, effect_bold); + echo (data); + terminal_cancel (); + exit (log_failure); +} + +int main (void) { + char * buffer = null; + int offset = 0; + int length = 0; + + buffer = file_import ("./test.x"); + + for (offset = 0; buffer [offset] != '\0'; ++offset) { + if ((buffer [offset] == '-') && (buffer [offset + 1] == '-') && (buffer [offset + 2] == '-') && (buffer [offset + 1] != '\0') && (buffer [offset + 2] != '\0')) { + for (; buffer [offset] != '\n'; ++offset); + } else if (buffer [offset] == '"') { + int size = 0; + char data [STRING_LIMIT] = ""; + for (++offset; (buffer [offset] != '"') && (buffer [offset] != '\0'); ++offset) { + data [size++] = buffer [offset]; + } + data [size] = '\0'; + add_token (core_string, string_code); + add_string (data, size); + } else if (character_is_digit (buffer [offset]) == true) { + int data = buffer [offset] - '0'; + for (++offset; (character_is_digit (buffer [offset]) == true) && (buffer [offset] != '\0'); ++offset) { + data *= 10; + data += (buffer [offset] - '0'); + } + add_token (core_number, number_code); + add_number (data); + --offset; + } else if (character_is_alpha (buffer [offset]) == true) { + int size = 0; + char name [NAME_LIMIT] = ""; + for (; ((character_is_alpha (buffer [offset]) == true) || + (character_is_digit (buffer [offset]) == true) || + (character_is_underscore (buffer [offset]) == true)) && (buffer [offset] != '\0'); ++offset) { + name [size++] = buffer [offset]; + } + name [size] = '\0'; + for (length = 0; length < 10; ++length) { + if (string_compare_limit (name, word_list [length], string_length (word_list [length]) + 1) == true) { + add_token (core_word, length); + goto here; + } + } + add_token (core_marker, marker_code); + here: + add_marker (name, token_type [token_count - 1]); + --offset; + } else if (character_compare_array (buffer [offset], ",.;:=<>&|+-*/%(){}") == true) { + add_token (core_symbol, symbol_code); + add_symbol (buffer [offset]); + } else { + if (character_is_blank (buffer [offset]) == false) { + echo ("\033[1;31mSegmentation fault motherfucker!\033[0m\n"); + printf ("%c -- %i\n", buffer [offset], (int) buffer [offset]); + exit (log_failure); + } + } + } + + for (length = 0; length < token_count; ++length) { + switch (token_type [length]) { + case core_symbol: printf ("\033[1;34m%c\033[0m ", symbol_data [token_data [length]]); break; + case core_string: printf ("\033[1;31m%s\033[0m ", string_data [token_data [length]]); break; + case core_number: printf ("\033[1;32m%i\033[0m ", number_data [token_data [length]]); break; + case core_marker: printf ("\033[1;33m%s\033[0m ", marker_name [token_data [length]]); break; + case core_word: printf ("\033[1;35m%s\033[0m ", word_list [token_data [length]]); break; + default: break; + } + } + + printf ("\n"); + + for (length = 0; length < token_count; ++length) { + if ((token_type [length] == core_word) && (token_data [length] == word_return)) { + ++length; + if ((token_type [length] == core_symbol) && (symbol_data [token_data [length]] == '(')) { + echo ("return (\n"); + ++length; + } else if ((token_type [length] == core_symbol) && (symbol_data [token_data [length]] == ';')) { + echo ("return ; -- 48 33 C0 3C -- xor rax rax ret\n"); + ++length; + } else { + kill ("return ?\n"); + } + } else if ((token_type [length] == core_word) && (token_data [length] == word_if)) { + ++length; + if ((token_type [length] == core_symbol) && (symbol_data [token_data [length]] == '(')) { + echo ("if (\n"); + ++length; + } else { + kill ("if ?\n"); + } + } else if ((token_type [length] == core_word) && (token_data [length] == word_else)) { + ++length; + if ((token_type [length] == core_symbol) && (symbol_data [token_data [length]] == ':')) { + echo ("else :\n"); + ++length; + } else if ((token_type [length] == core_word) && (token_data [length] == word_if)) { + echo ("else if\n"); + ++length; + } else { + kill ("else ?\n"); + } + } else if ((token_type [length] == core_word) && (token_data [length] == word_type)) { + ++length; + if (token_type [length] == core_marker) { + echo ("type -- "); + echo (marker_name [token_data [length]]); + echo ("\n"); + ++length; + } else { + kill ("type ?\n"); + } + } + } + + for (length = 0; length < string_code; ++length) { string_data [length] = deallocate (string_data [length]); } + for (length = 0; length < marker_code; ++length) { marker_name [length] = deallocate (marker_name [length]); } + + string_data = deallocate (string_data); + string_size = deallocate (string_size); + marker_name = deallocate (marker_name); + marker_type = deallocate (marker_type); + symbol_data = deallocate (symbol_data); + number_data = deallocate (number_data); + token_data = deallocate (token_data); + token_type = deallocate (token_type); + + buffer = deallocate (buffer); + + return (log_success); +}