Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Naruzzo committed May 29, 2024
0 parents commit 7c37fa1
Show file tree
Hide file tree
Showing 13 changed files with 440 additions and 0 deletions.
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
CC = gcc
CFLAGS = -Wall -Wextra -std=c99
SRCS = src/main.c src/lexer.c src/parser.c src/interpreter.c
OBJS = $(SRCS:.c=.o)
EXEC = uzbeklang

all: $(EXEC)

$(EXEC): $(OBJS)
$(CC) $(CFLAGS) -o $(EXEC) $(OBJS)

clean:
rm -f $(OBJS) $(EXEC)

.PHONY: all clean
3 changes: 3 additions & 0 deletions examples/uzbeklang.uzb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Yoz "Mening ismim"
Yoz 14
Qosh 14 53;
38 changes: 38 additions & 0 deletions src/interpreter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <stdio.h>
#include "interpreter.h"

void interpret(ASTNode *node) {
if (!node) return;

switch (node->type) {
case AST_PRINT:
interpret(node->left);
break;
case AST_ADD: {
ASTNode *left = node->left;
ASTNode *right = node->right;
if (left->type == AST_NUMBER && right->type == AST_NUMBER) {
int result = atoi(left->value) + atoi(right->value);
printf("%d\n", result);
}
break;
}
case AST_SUB: {
ASTNode *left = node->left;
ASTNode *right = node->right;
if (left->type == AST_NUMBER && right->type == AST_NUMBER) {
int result = atoi(left->value) - atoi(right->value);
printf("%d\n", result);
}
break;
}
case AST_NUMBER:
printf("%s\n", node->value);
break;
case AST_STRING:
printf("%s\n", node->value);
break;
default:
break;
}
}
8 changes: 8 additions & 0 deletions src/interpreter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef INTERPRETER_H
#define INTERPRETER_H

#include "parser.h"

void interpret(ASTNode *node);

#endif
Binary file added src/interpreter.o
Binary file not shown.
118 changes: 118 additions & 0 deletions src/lexer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "lexer.h"

Lexer *init_lexer(char *source) {
Lexer *lexer = (Lexer *)malloc(sizeof(Lexer));
lexer->source = source;
lexer->length = strlen(source);
lexer->pos = 0;
return lexer;
}

void free_lexer(Lexer *lexer) {
free(lexer);
}

Token *create_token(TokenType type, char *value) {
Token *token = (Token *)malloc(sizeof(Token));
token->type = type;
token->value = value;
return token;
}

void free_token(Token *token) {
if (token->value) free(token->value);
free(token);
}

char peek(Lexer *lexer) {
if (lexer->pos < lexer->length) {
return lexer->source[lexer->pos];
}
return '\0';
}

char advance(Lexer *lexer) {
lexer->pos++;
return peek(lexer);
}

void skip_whitespace(Lexer *lexer) {
while (isspace(peek(lexer))) {
advance(lexer);
}
}

Token *get_next_token(Lexer *lexer) {
skip_whitespace(lexer);

char current = peek(lexer);

if (current == '\0') {
return create_token(TOKEN_EOF, NULL);
}

if (isalpha(current)) {
size_t start = lexer->pos;
while (isalpha(peek(lexer))) advance(lexer);

size_t length = lexer->pos - start;
char *value = (char *)malloc(length + 1);
strncpy(value, lexer->source + start, length);
value[length] = '\0';

if (strcmp(value, "Yoz") == 0) return create_token(TOKEN_PRINT, value);
if (strcmp(value, "Qosh") == 0) return create_token(TOKEN_ADD, value);
if (strcmp(value, "Ayir") == 0) return create_token(TOKEN_SUB, value);

return create_token(TOKEN_ID, value);
}

if (isdigit(current)) {
size_t start = lexer->pos;
while (isdigit(peek(lexer))) advance(lexer);

size_t length = lexer->pos - start;
char *value = (char *)malloc(length + 1);
strncpy(value, lexer->source + start, length);
value[length] = '\0';

return create_token(TOKEN_NUMBER, value);
}

if (current == '\"') {
advance(lexer); // Skip the opening quote
size_t start = lexer->pos;

while (peek(lexer) != '\"' && peek(lexer) != '\0') advance(lexer);

size_t length = lexer->pos - start;
char *value = (char *)malloc(length + 1);
strncpy(value, lexer->source + start, length);
value[length] = '\0';

advance(lexer); // Skip the closing quote

return create_token(TOKEN_STRING, value);
}

if (current == '(') {
advance(lexer);
return create_token(TOKEN_LPAREN, strdup("("));
}

if (current == ')') {
advance(lexer);
return create_token(TOKEN_RPAREN, strdup(")"));
}

if (current == ';') {
advance(lexer);
return create_token(TOKEN_SEMICOLON, strdup(";"));
}

return create_token(TOKEN_ERROR, NULL);
}
34 changes: 34 additions & 0 deletions src/lexer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef LEXER_H
#define LEXER_H

typedef enum {
TOKEN_EOF,
TOKEN_ID,
TOKEN_STRING,
TOKEN_NUMBER,
TOKEN_PRINT,
TOKEN_ADD,
TOKEN_SUB,
TOKEN_LPAREN,
TOKEN_RPAREN,
TOKEN_SEMICOLON,
TOKEN_ERROR
} TokenType;

typedef struct {
TokenType type;
char *value;
} Token;

typedef struct {
char *source;
size_t length;
size_t pos;
} Lexer;

Lexer *init_lexer(char *source);
Token *get_next_token(Lexer *lexer);
void free_lexer(Lexer *lexer);
void free_token(Token *token);

#endif
Binary file added src/lexer.o
Binary file not shown.
70 changes: 70 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include <stdio.h>
#include <stdlib.h>
#include "lexer.h"
#include "parser.h"
#include "interpreter.h"

void run_repl() {
char input[256];

printf("UzbekLang dasturiga xush kelibsiz!\n");

while (1) {
printf(">> ");
if (!fgets(input, sizeof(input), stdin)) break;
if (strncmp(input, "exit", 4) == 0) break;

Lexer *lexer = init_lexer(input);
Parser *parser = init_parser(lexer);
ASTNode *root = parse(parser);

interpret(root);

free_ast(root);
free_parser(parser);
free_lexer(lexer);
}
}

void run_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (!file) {
fprintf(stderr, "Faylni ochib bo'lmadi: %s\n", filename);
exit(1);
}

fseek(file, 0, SEEK_END);
long length = ftell(file);
fseek(file, 0, SEEK_SET);

char *input = (char *)malloc(length + 1);
if (!input) {
fprintf(stderr, "Xotirani ajratib bo'lmadi\n");
exit(1);
}

fread(input, 1, length, file);
input[length] = '\0';
fclose(file);

Lexer *lexer = init_lexer(input);
Parser *parser = init_parser(lexer);
ASTNode *root = parse(parser);

interpret(root);

free_ast(root);
free_parser(parser);
free_lexer(lexer);
free(input);
}

int main(int argc, char **argv) {
if (argc == 2) {
run_file(argv[1]);
} else {
run_repl();
}

return 0;
}
Binary file added src/main.o
Binary file not shown.
Loading

0 comments on commit 7c37fa1

Please sign in to comment.