update readme
This commit is contained in:
parent
e4a32bd40d
commit
4b08e74c3a
8 changed files with 218 additions and 108 deletions
6
Makefile
6
Makefile
|
@ -10,10 +10,10 @@ BINDIR = $(PREFIX)/bin
|
||||||
MANDIR = $(PREFIX)/share/man/man1
|
MANDIR = $(PREFIX)/share/man/man1
|
||||||
|
|
||||||
# Flags
|
# Flags
|
||||||
LDFLAGS = $(shell pkg-config --libs)
|
LDFLAGS =
|
||||||
CFLAGS = -O3 -march=native -mtune=native -pipe -g -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 $(shell pkg-config --cflags)
|
CFLAGS = -O3 -march=native -mtune=native -pipe -s -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600
|
||||||
|
|
||||||
SRC = slr.c lexer.c
|
SRC = slr.c lexer.c parser.c
|
||||||
|
|
||||||
$(TARGET): $(SRC)
|
$(TARGET): $(SRC)
|
||||||
$(CC) $(SRC) -o $@ $(CFLAGS) $(LDFLAGS)
|
$(CC) $(SRC) -o $@ $(CFLAGS) $(LDFLAGS)
|
||||||
|
|
13
README.md
13
README.md
|
@ -1,7 +1,18 @@
|
||||||
# S Lang Runtime
|
# S Lang Runtime
|
||||||
|
|
||||||
S Lang(Slang) Runtime is a interpreter for Slang.
|
S Lang(Slang) Runtime is a interpreter for Slang.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
# Depedencies
|
||||||
|
None
|
||||||
|
|
||||||
|
# Building
|
||||||
|
You will need to run these with elevated privilages.
|
||||||
|
```
|
||||||
|
$ make
|
||||||
|
# make install
|
||||||
|
```
|
||||||
|
|
||||||
# Contributions
|
# Contributions
|
||||||
Contributions are welcomed, feel free to open a pull request.
|
Contributions are welcomed, feel free to open a pull request.
|
||||||
|
|
||||||
|
|
95
lexer.c
95
lexer.c
|
@ -14,35 +14,17 @@ Token *lexer(char *buf)
|
||||||
while(current[current_index] != '\0') {
|
while(current[current_index] != '\0') {
|
||||||
Token *token = NULL;
|
Token *token = NULL;
|
||||||
if(current[current_index] == ';') {
|
if(current[current_index] == ';') {
|
||||||
token = malloc(sizeof(Token));
|
token = generate_separator(current, ¤t_index);
|
||||||
char *value = malloc(2 * sizeof(char));
|
|
||||||
value[0] = current[current_index];
|
|
||||||
value[1] = '\0';
|
|
||||||
token->value = value;
|
|
||||||
token->type = SEPARATOR;
|
|
||||||
tokens[tokens_index] = *token;
|
tokens[tokens_index] = *token;
|
||||||
tokens_index++;
|
tokens_index++;
|
||||||
printf("FOUND SEMICOLON\n");
|
|
||||||
} else if(current[current_index] == '(') {
|
} else if(current[current_index] == '(') {
|
||||||
token = malloc(sizeof(Token));
|
token = generate_separator(current, ¤t_index);
|
||||||
char *value = malloc(2 * sizeof(char));
|
|
||||||
value[0] = current[current_index];
|
|
||||||
value[1] = '\0';
|
|
||||||
token->value = value;
|
|
||||||
token->type = SEPARATOR;
|
|
||||||
tokens[tokens_index] = *token;
|
tokens[tokens_index] = *token;
|
||||||
tokens_index++;
|
tokens_index++;
|
||||||
printf("FOUND OPEN PAREN\n");
|
|
||||||
} else if(current[current_index] == ')') {
|
} else if(current[current_index] == ')') {
|
||||||
token = malloc(sizeof(Token));
|
token = generate_separator(current, ¤t_index);
|
||||||
char *value = malloc(2 * sizeof(char));
|
|
||||||
value[0] = current[current_index];
|
|
||||||
value[1] = '\0';
|
|
||||||
token->value = value;
|
|
||||||
token->type = SEPARATOR;
|
|
||||||
tokens[tokens_index] = *token;
|
tokens[tokens_index] = *token;
|
||||||
tokens_index++;
|
tokens_index++;
|
||||||
printf("FOUND CLOSE PAREN\n");
|
|
||||||
} else if(isdigit(current[current_index])) {
|
} else if(isdigit(current[current_index])) {
|
||||||
token = generate_number(current, ¤t_index);
|
token = generate_number(current, ¤t_index);
|
||||||
tokens[tokens_index] = *token;
|
tokens[tokens_index] = *token;
|
||||||
|
@ -54,9 +36,6 @@ Token *lexer(char *buf)
|
||||||
tokens_index++;
|
tokens_index++;
|
||||||
current_index--;
|
current_index--;
|
||||||
}
|
}
|
||||||
if (token != NULL) {
|
|
||||||
print_token(*token);
|
|
||||||
}
|
|
||||||
current_index++;
|
current_index++;
|
||||||
}
|
}
|
||||||
tokens[tokens_index].type = END_OF_TOKENS;
|
tokens[tokens_index].type = END_OF_TOKENS;
|
||||||
|
@ -64,3 +43,71 @@ Token *lexer(char *buf)
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_token(Token token)
|
||||||
|
{
|
||||||
|
printf("Token Value: \"");
|
||||||
|
for (int i = 0; token.value[i] != '\0'; i++) {
|
||||||
|
printf("%c", token.value[i]);
|
||||||
|
}
|
||||||
|
printf("\"\nToken Type: ");
|
||||||
|
switch (token.type) {
|
||||||
|
case INT:
|
||||||
|
printf("int\n");
|
||||||
|
break;
|
||||||
|
case KEYWORD:
|
||||||
|
printf("Keyword\n");
|
||||||
|
break;
|
||||||
|
case SEPARATOR:
|
||||||
|
printf("Separator\n");
|
||||||
|
break;
|
||||||
|
case END_OF_TOKENS:
|
||||||
|
printf("End of Tokens\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Token *generate_separator(char *current, int *current_index)
|
||||||
|
{
|
||||||
|
Token *token = malloc(sizeof(Token));
|
||||||
|
token->value = malloc(sizeof(char) * 2);
|
||||||
|
token->value[0] = current[*current_index];
|
||||||
|
token->value[1] = '\0';
|
||||||
|
token->type = SEPARATOR;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token *generate_number(char *current, int *current_index)
|
||||||
|
{
|
||||||
|
Token *token = malloc(sizeof(Token));
|
||||||
|
token->type = INT;
|
||||||
|
char *value = malloc(8 * sizeof(char));
|
||||||
|
int value_index = 0;
|
||||||
|
while(isdigit(current[*current_index]) && current[*current_index] != '\0') {
|
||||||
|
value[value_index] = current[*current_index];
|
||||||
|
value_index++;
|
||||||
|
(*current_index)++;
|
||||||
|
}
|
||||||
|
value[value_index] = '\0';
|
||||||
|
token->value = value;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token *generate_keyword(char *current, int *current_index)
|
||||||
|
{
|
||||||
|
Token *token = malloc(sizeof(Token));
|
||||||
|
char *keyword = malloc(8 * sizeof(char));
|
||||||
|
int keyword_index = 0;
|
||||||
|
while(isalpha(current[*current_index]) && current[*current_index] != '\0') {
|
||||||
|
keyword[keyword_index] = current[*current_index];
|
||||||
|
keyword_index++;
|
||||||
|
(*current_index)++;
|
||||||
|
}
|
||||||
|
keyword[keyword_index] = '\0';
|
||||||
|
if(strcmp(keyword, "exit") == 0) {
|
||||||
|
printf("TYPE EXIT\n");
|
||||||
|
token->type = KEYWORD;
|
||||||
|
}
|
||||||
|
token->type = KEYWORD;
|
||||||
|
token->value = keyword;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
16
lexer.h
16
lexer.h
|
@ -1,8 +1,22 @@
|
||||||
#ifndef LEXER_H_
|
#ifndef LEXER_H_
|
||||||
#define LEXER_H_
|
#define LEXER_H_
|
||||||
|
|
||||||
#include "slr.h"
|
typedef enum {
|
||||||
|
INT,
|
||||||
|
KEYWORD,
|
||||||
|
SEPARATOR,
|
||||||
|
END_OF_TOKENS,
|
||||||
|
} TokenType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TokenType type;
|
||||||
|
char *value;
|
||||||
|
} Token;
|
||||||
|
|
||||||
Token *lexer(char *buf);
|
Token *lexer(char *buf);
|
||||||
|
void print_token(Token token);
|
||||||
|
Token *generate_separator(char *current, int *current_index);
|
||||||
|
Token *generate_number(char *current, int *current_index);
|
||||||
|
Token *generate_keyword(char *current, int *current_index);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
102
parser.c
Normal file
102
parser.c
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "lexer.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
INT_LIT,
|
||||||
|
STATEMENT,
|
||||||
|
EXTRA,
|
||||||
|
BEGINNING,
|
||||||
|
} NodeTypes;
|
||||||
|
|
||||||
|
typedef struct Node {
|
||||||
|
char *value;
|
||||||
|
NodeTypes type;
|
||||||
|
struct Node *right;
|
||||||
|
struct Node *left;
|
||||||
|
} Node;
|
||||||
|
|
||||||
|
void print_tree(Node *node){
|
||||||
|
if(node == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(size_t i = 0; node->value[i] != '\0'; i++){
|
||||||
|
printf("%c", node->value[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
print_tree(node->left);
|
||||||
|
print_tree(node->right);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *init_node(Node *node, char *value, NodeTypes type){
|
||||||
|
node = malloc(sizeof(Node));
|
||||||
|
node->value = malloc(sizeof(char) * 2);
|
||||||
|
node->type = (int)type;
|
||||||
|
node->value = value;
|
||||||
|
node->left = NULL;
|
||||||
|
node->right = NULL;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token *parser(Token *tokens){
|
||||||
|
Token *current_token = &tokens[0];
|
||||||
|
Node *root = malloc(sizeof(Node));
|
||||||
|
Node *left = malloc(sizeof(Node));
|
||||||
|
Node *right = malloc(sizeof(Node));
|
||||||
|
root = init_node(root, "PROGRAM", BEGINNING);
|
||||||
|
|
||||||
|
print_tree(root);
|
||||||
|
|
||||||
|
Node *current = root;
|
||||||
|
|
||||||
|
while(current_token->type != END_OF_TOKENS){
|
||||||
|
if(current == NULL){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(current == root){
|
||||||
|
//;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(current_token->type == KEYWORD && strcmp(current_token->value, "exit")){
|
||||||
|
Node *exit_node = malloc(sizeof(Node));
|
||||||
|
exit_node = init_node(exit_node, current_token->value, STATEMENT);
|
||||||
|
root->right = exit_node;
|
||||||
|
current = exit_node;
|
||||||
|
current_token++;
|
||||||
|
if(current_token->type != SEPARATOR){
|
||||||
|
printf("ERROR\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
Node *open_paren_node = malloc(sizeof(Node));
|
||||||
|
open_paren_node = init_node(open_paren_node, current_token->value, EXTRA);
|
||||||
|
current->left = open_paren_node;
|
||||||
|
|
||||||
|
current_token++;
|
||||||
|
|
||||||
|
Node *expr_node = malloc(sizeof(Node));
|
||||||
|
expr_node = init_node(expr_node, current_token->value, INT_LIT);
|
||||||
|
current->left->left = expr_node;
|
||||||
|
|
||||||
|
current_token++;
|
||||||
|
|
||||||
|
Node *close_paren_node = malloc(sizeof(Node));
|
||||||
|
close_paren_node = init_node(close_paren_node, current_token->value, EXTRA);
|
||||||
|
current->left->right = close_paren_node;
|
||||||
|
|
||||||
|
current_token++;
|
||||||
|
|
||||||
|
Node *semi_node = malloc(sizeof(Node));
|
||||||
|
semi_node = init_node(semi_node, current_token->value, EXTRA);
|
||||||
|
current->right = semi_node;
|
||||||
|
|
||||||
|
printf("EXIT\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current_token++;
|
||||||
|
}
|
||||||
|
print_tree(root);
|
||||||
|
return current_token;
|
||||||
|
}
|
6
parser.h
Normal file
6
parser.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef PARSER_H_
|
||||||
|
#define PARSER_H_
|
||||||
|
|
||||||
|
Token *parser(Token *tokens);
|
||||||
|
|
||||||
|
#endif
|
68
slr.c
68
slr.c
|
@ -3,64 +3,8 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "slr.h"
|
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
|
#include "parser.h"
|
||||||
void print_token(Token token)
|
|
||||||
{
|
|
||||||
printf("Token Value: ");
|
|
||||||
for (int i = 0; token.value[i] != '\0'; i++) {
|
|
||||||
printf("%c", token.value[i]);
|
|
||||||
}
|
|
||||||
printf("\nToken Type: ");
|
|
||||||
switch (token.type) {
|
|
||||||
case INT:
|
|
||||||
printf("int\n");
|
|
||||||
break;
|
|
||||||
case KEYWORD:
|
|
||||||
printf("Keyword\n");
|
|
||||||
break;
|
|
||||||
case SEPARATOR:
|
|
||||||
printf("Separator\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Token *generate_number(char *current, int *current_index)
|
|
||||||
{
|
|
||||||
Token *token = malloc(sizeof(Token));
|
|
||||||
token->type = INT;
|
|
||||||
char *value = malloc(8 * sizeof(char));
|
|
||||||
int value_index = 0;
|
|
||||||
while(isdigit(current[*current_index]) && current[*current_index] != '\0') {
|
|
||||||
value[value_index] = current[*current_index];
|
|
||||||
value_index++;
|
|
||||||
(*current_index)++;
|
|
||||||
}
|
|
||||||
value[value_index] = '\0';
|
|
||||||
token->value = value;
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token *generate_keyword(char *current, int *current_index)
|
|
||||||
{
|
|
||||||
Token *token = malloc(sizeof(Token));
|
|
||||||
char *keyword = malloc(8 * sizeof(char));
|
|
||||||
int keyword_index = 0;
|
|
||||||
while(isalpha(current[*current_index]) && current[*current_index] != '\0') {
|
|
||||||
keyword[keyword_index] = current[*current_index];
|
|
||||||
keyword_index++;
|
|
||||||
(*current_index)++;
|
|
||||||
}
|
|
||||||
keyword[keyword_index] = '\0';
|
|
||||||
if(strcmp(keyword, "exit") == 0) {
|
|
||||||
printf("TYPE EXIT\n");
|
|
||||||
token->type = KEYWORD;
|
|
||||||
}
|
|
||||||
token->type = KEYWORD;
|
|
||||||
token->value = keyword;
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
long long get_file_length(FILE *file)
|
long long get_file_length(FILE *file)
|
||||||
{
|
{
|
||||||
|
@ -70,18 +14,24 @@ long long get_file_length(FILE *file)
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
fprintf(stderr, "\033[1;37mslr:\033[0m \033[1;31mfatal error:\033[0m no input files\ninterpretation termined.\n");
|
fprintf(stderr, "\033[1;37mslr:\033[0m \033[1;31mfatal error:\033[0m no input files\ninterpretation termined.\n");
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
FILE *file = fopen(argv[1], "r");
|
FILE *file = fopen(argv[1], "r");
|
||||||
|
if (!file) {
|
||||||
|
perror("fopen");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
long long length = get_file_length(file);
|
long long length = get_file_length(file);
|
||||||
char *buf = malloc(length * sizeof(char));
|
char *buf = malloc(length * sizeof(char));
|
||||||
fread(buf, 1, length, file);
|
fread(buf, 1, length, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
buf[length + 1] = '\0';
|
buf[length + 1] = '\0';
|
||||||
Token *tokens = lexer(buf);
|
Token *tokens = lexer(buf);
|
||||||
|
for(size_t i = 0; tokens[i].type != END_OF_TOKENS; i++){
|
||||||
|
print_token(tokens[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
20
slr.h
20
slr.h
|
@ -1,20 +0,0 @@
|
||||||
#ifndef SLR_H_
|
|
||||||
#define SLR_H_
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
INT,
|
|
||||||
KEYWORD,
|
|
||||||
SEPARATOR,
|
|
||||||
END_OF_TOKENS,
|
|
||||||
} TokenType;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
TokenType type;
|
|
||||||
char *value;
|
|
||||||
} Token;
|
|
||||||
|
|
||||||
void print_token(Token token);
|
|
||||||
Token *generate_number(char *current, int *current_index);
|
|
||||||
Token *generate_keyword(char *current, int *current_index);
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in a new issue