Skip to content

Commit 4ad2d58

Browse files
Added repl mode
1 parent 6ebe99f commit 4ad2d58

File tree

8 files changed

+97
-72
lines changed

8 files changed

+97
-72
lines changed

mas/Makefile

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,31 @@
22
CC = gcc
33
CFLAGS = -Wall -Wextra
44

5-
# Target executable
6-
TARGET = mas.exe
5+
# Detect OS (Windows_NT is set on Windows)
6+
ifeq ($(OS),Windows_NT)
7+
RM = del /Q
8+
TARGET = mas.exe
9+
SHELL := cmd.exe
10+
PATHSEP = \\
11+
else
12+
RM = rm -f
13+
TARGET = mas
14+
SHELL := /bin/sh
15+
PATHSEP = /
16+
endif
717

818
# Source files
919
SRCS = lexer.c parser.c interpreter.c main.c
1020

1121
# Default target
1222
all: $(TARGET)
1323

14-
# Link object files into executable
24+
# Build target
1525
$(TARGET): $(SRCS)
1626
$(CC) $(CFLAGS) -o $@ $^
1727

18-
# Clean generated files
28+
# Clean target
1929
clean:
20-
del $(TARGET) 2> NUL || rm -f $(TARGET)
30+
-$(RM) $(TARGET)
2131

22-
.PHONY: all clean
32+
.PHONY: all clean

mas/lexer.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,26 @@ static int line = 1;
66
static FILE* file;
77
static bool eof_reached = false;
88

9+
ExecutionMode mode;
10+
911
void lexer_init(FILE* f) {
12+
//Setting the lexer mode
13+
mode = FILE_MODE;
1014
file = f;
1115
current = NULL;
1216
}
1317

18+
void lexer_init_repl(char* code){
19+
//Setting the lexer mode
20+
mode = REPL_MODE;
21+
22+
int size = strlen(code);
23+
char* buffer = malloc(size + 1);
24+
strcpy(buffer, code);
25+
buffer[size] = '\0';
26+
current = buffer;
27+
}
28+
1429
// Helper function to read next character
1530
static int next_char() {
1631
if (current && *current) {
@@ -166,7 +181,7 @@ static Token* make_token(TokenType type, char* value, int line_num) {
166181

167182
// Main lexer function
168183
Token* lexer_next() {
169-
if (!current) {
184+
if (!current && mode == FILE_MODE) {
170185
// Read entire file into memory
171186
fseek(file, 0, SEEK_END);
172187
long size = ftell(file);

mas/main.c

Lines changed: 39 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,67 +2,49 @@
22
#include "mas.h"
33
#include <stdio.h>
44

5+
56
int main(int argc, char* argv[]) {
6-
if (argc != 2) {
7-
fprintf(stderr, "Usage: %s <input.mas>\n", argv[0]);
7+
if(argc >2){
8+
fprintf(stderr, "Too many arguments provided\n");
89
return 1;
910
}
10-
11-
FILE* f = fopen(argv[1], "rb");
12-
if (!f) {
13-
perror("Failed to open file");
14-
return 1;
11+
else if(argc == 1){
12+
// REPL mode
13+
printf("MAS Programming Language REPL \n");
14+
printf("Type 'exit to quit\n");
15+
16+
char input[REPL_INPUT_SIZE];
17+
18+
while(1){
19+
printf("mas >>");
20+
if(!(fgets(input, REPL_INPUT_SIZE, stdin))) continue;
21+
22+
// Check for exit command
23+
if(strcmp(input, "exit\n") ==0){
24+
printf("Exiting MAS REPL. Goodbye!\n");
25+
break;
26+
}
27+
28+
lexer_init_repl(input);
29+
ASTNode* ast = parse_program();
30+
interpret(ast);
31+
}
32+
}
33+
else{
34+
//Execution from file
35+
FILE* f = fopen(argv[1], "rb");
36+
if (!f) {
37+
perror("Failed to open file");
38+
return 1;
39+
}
40+
41+
lexer_init(f);
42+
43+
ASTNode* ast = parse_program();
44+
fclose(f);
45+
46+
interpret(ast);
1547
}
16-
17-
lexer_init(f);
18-
19-
20-
21-
// Token* tok;
22-
// do {
23-
// tok = lexer_next();
24-
// switch (tok->type) {
25-
// case TOK_EOF:
26-
// printf("EOF\n");
27-
// break;
28-
// case TOK_ERROR:
29-
// printf("ERROR (line %d): %s\n", tok->line, tok->value);
30-
// break;
31-
// case TOK_NUMBER:
32-
// printf("NUMBER (line %d): %s\n", tok->line, tok->value);
33-
// break;
34-
// case TOK_STRING:
35-
// printf("STRING (line %d): \"%s\"\n", tok->line, tok->value);
36-
// break;
37-
// case TOK_ID:
38-
// printf("IDENTIFIER (line %d): %s\n", tok->line, tok->value);
39-
// break;
40-
// case TOK_NEWLINE:
41-
// printf("NEWLINE (line %d)\n", tok->line);
42-
// break;
43-
// case TOK_PLUS: printf("PLUS (line %d)\n", tok->line); break;
44-
// case TOK_ASSIGN: printf("ASSIGN '=' (line %d)\n", tok->line); break;
45-
// case TOK_EQ: printf("EQ '==' (line %d)\n", tok->line); break;
46-
// // ... add more as needed, or use a helper function ...
47-
// default:
48-
// // For brevity, just print type and value
49-
// printf("TOKEN %d (line %d): %s\n", tok->type, tok->line, tok->value ? tok->value : "");
50-
// break;
51-
// }
52-
53-
// TokenType type = tok->type;
54-
55-
// // Clean up
56-
// if (tok->value) free(tok->value);
57-
// free(tok);
58-
59-
// if (type == TOK_EOF) break;
60-
// }while(1);
61-
62-
ASTNode* ast = parse_program();
63-
fclose(f);
64-
65-
interpret(ast);
6648

6749
return 0;
6850
}

mas/mas

39.6 KB
Binary file not shown.

mas/mas.exe

-67.2 KB
Binary file not shown.

mas/mas.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#include <string.h>
99
#include <stdbool.h>
1010

11+
//Declaration for REPL mode size
12+
#define REPL_INPUT_SIZE 1024
13+
1114
// Token types
1215
typedef enum {
1316
TOK_ID, TOK_NUMBER, TOK_STRING, TOK_PLUS, TOK_MINUS, TOK_TIMES, TOK_DIVIDE,
@@ -83,8 +86,17 @@ struct ASTNode {
8386
} data;
8487
};
8588

89+
//Execution mode
90+
typedef enum {
91+
FILE_MODE,
92+
REPL_MODE
93+
} ExecutionMode;
94+
95+
extern ExecutionMode mode;
96+
8697
// Function declarations
8798
void lexer_init(FILE* f);
99+
void lexer_init_repl(char* code);
88100
Token* lexer_next();
89101
ASTNode* parse_program();
90102
MASObject* interpret(ASTNode* ast);

mas/parser.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ static bool match(TokenType type) {
2121

2222
static void consume(TokenType type, const char* message) {
2323
if (!match(type)) {
24-
fprintf(stderr, "Parse error at line %d: %s\n",
25-
current_token ? current_token->line : -1, message);
24+
if (mode == FILE_MODE) (stderr, "Parse error at line %d: ", current_token ? current_token->line : -1);
25+
fprintf(stderr, "%s\n", message);
2626
exit(1);
2727
}
2828
advance();
@@ -76,7 +76,8 @@ ASTNode* parse_statement() {
7676
advance(); // consume 'def'
7777

7878
if (!match(TOK_ID)) {
79-
fprintf(stderr, "Parse error at line %d: Expected function name\n", current_token->line);
79+
if (mode == FILE_MODE) fprintf(stderr, "Parse error at line %d: ",current_token->line);
80+
fprintf(stderr, "Expected function name\n");
8081
exit(1);
8182
}
8283
char* func_name = strdup(current_token->value);
@@ -90,7 +91,8 @@ ASTNode* parse_statement() {
9091
if (!match(TOK_RPAREN)) {
9192
do {
9293
if (!match(TOK_ID)) {
93-
fprintf(stderr, "Parse error at line %d: Expected parameter name\n", current_token->line);
94+
if (mode == FILE_MODE) fprintf(stderr, "Parse error at line %d: ",current_token->line);
95+
fprintf(stderr,"Expected parameter name\n");
9496
exit(1);
9597
}
9698
params[param_count++] = strdup(current_token->value);
@@ -155,7 +157,8 @@ ASTNode* parse_statement() {
155157
advance(); // consume 'each'
156158

157159
if (!match(TOK_ID)) {
158-
fprintf(stderr, "Parse error at line %d: Expected variable name\n", current_token->line);
160+
if (mode == FILE_MODE) fprintf(stderr, "Parse error at line %d: ",current_token->line);
161+
fprintf(stderr, "Expected variable name\n");
159162
exit(1);
160163
}
161164
char* target = strdup(current_token->value);
@@ -333,7 +336,8 @@ ASTNode* parse_comparison() {
333336
if (match(TOK_ASSIGN)) {
334337
advance(); // consume '='
335338
if (expr->type != AST_VAR && expr->type != AST_INDEX) {
336-
fprintf(stderr, "Parse error at line %d: Invalid assignment target.\n", expr->line);
339+
if (mode == FILE_MODE) fprintf(stderr, "Parse error at line %d: ",current_token->line);
340+
fprintf(stderr, "Invalid assignment target.\n");
337341
exit(1);
338342
}
339343
ASTNode* value = parse_expression();
@@ -627,8 +631,8 @@ ASTNode* parse_primary() {
627631
return expr;
628632
}
629633

630-
fprintf(stderr, "Parse error at line %d: Unexpected token\n",
631-
current_token ? current_token->line : -1);
634+
if (mode == FILE_MODE) fprintf(stderr, "Parse error at line %d: ", current_token ? current_token->line : -1);
635+
fprintf(stderr, "Unexpected token\n");
632636
exit(1);
633637
}
634638

mas/test.mas

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"Hello"
2+
13
# Hello World
24
print "Hello, MAS!"
35

0 commit comments

Comments
 (0)