1
0
Fork 0
This commit is contained in:
Alex Kotov 2023-05-04 14:16:58 +04:00
parent bff63075d0
commit f7b2817f55
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
4 changed files with 203 additions and 199 deletions

View file

@ -3,7 +3,7 @@ all: lisp
CC = gcc
CFLAGS = -Wall -Wextra
OBJS = enums.c.o main.c.o object.c.o tokens.c.o
OBJS = enums.c.o lexer.c.o main.c.o object.c.o tokens.c.o
run: lisp
./lisp

195
lexer.c Normal file
View file

@ -0,0 +1,195 @@
#include "lexer.h"
#include "enums.h"
#include "tokens.h"
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
static char buffer[1024];
static size_t buffer_index = 0;
static enum State state = STATE_INIT;
static void buffer_add(char chr);
static void buffer_clean();
static void token_add(enum State state, char *val);
void buffer_add(char chr)
{
assert(buffer_index < 1000);
buffer[buffer_index++] = chr;
buffer[buffer_index] = 0;
}
void buffer_clean()
{
buffer_index = 0;
}
void token_add(enum State state, char *val)
{
if (state == STATE_WHITESPACE) return;
enum TokenType token_type;
assert(State_to_token_type(state, &token_type));
tokens_push(token_type, val);
}
void lex(const char chr)
{
switch (state) {
case STATE_INIT:
if (chr == '(') {
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
state = STATE_WHITESPACE;
buffer_add(chr);
} else if (isalpha(chr)) {
state = STATE_ATOM;
buffer_add(chr);
} else if (isdigit(chr)) {
state = STATE_NUM;
buffer_add(chr);
} else {
abort();
}
break;
case STATE_WHITESPACE:
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
buffer_add(chr);
} else if (isalpha(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_ATOM;
buffer[buffer_index++] = chr;
} else if (isdigit(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_NUM;
buffer[buffer_index++] = chr;
} else {
abort();
}
break;
case STATE_OPEN:
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_WHITESPACE;
buffer_add(chr);
} else if (isalpha(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_ATOM;
buffer_add(chr);
} else if (isdigit(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_NUM;
buffer_add(chr);
} else {
abort();
}
break;
case STATE_CLOSE:
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_WHITESPACE;
buffer_add(chr);
} else if (isalpha(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_ATOM;
buffer_add(chr);
} else if (isdigit(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_NUM;
buffer_add(chr);
} else {
abort();
}
break;
case STATE_ATOM:
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_WHITESPACE;
buffer_add(chr);
} else if (isalnum(chr)) {
buffer_add(chr);
} else {
abort();
}
break;
case STATE_NUM:
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_WHITESPACE;
buffer_add(chr);
} else if (isdigit(chr)) {
buffer_add(chr);
} else {
abort();
}
break;
}
}

6
lexer.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef __LEXER_H__
#define __LEXER_H__
void lex(char chr);
#endif

199
main.c
View file

@ -1,30 +1,16 @@
#include "enums.h"
#include "lexer.h"
#include "object.h"
#include "tokens.h"
#include <assert.h>
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char buffer[1024];
static size_t buffer_index = 0;
static enum State state = STATE_INIT;
static void error(const char *msg);
/*********
* Lexer *
*********/
static void buffer_add(char chr);
static void buffer_clean();
static void token_add(enum State state, char *val);
static void lex(char chr);
/**********
* Parser *
**********/
@ -84,189 +70,6 @@ void error(const char *msg)
exit(EXIT_FAILURE);
}
/*********
* Lexer *
*********/
void buffer_add(char chr)
{
if (buffer_index >= 1000) error("token too long");
buffer[buffer_index++] = chr;
buffer[buffer_index] = 0;
}
void buffer_clean()
{
buffer_index = 0;
}
void token_add(enum State state, char *val)
{
if (state == STATE_WHITESPACE) return;
enum TokenType token_type;
if (!State_to_token_type(state, &token_type)) error("invalid state");
tokens_push(token_type, val);
}
void lex(char chr)
{
switch (state) {
case STATE_INIT:
if (chr == '(') {
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
state = STATE_WHITESPACE;
buffer_add(chr);
} else if (isalpha(chr)) {
state = STATE_ATOM;
buffer_add(chr);
} else if (isdigit(chr)) {
state = STATE_NUM;
buffer_add(chr);
} else {
error("invalid char (STATE_INIT)");
}
break;
case STATE_WHITESPACE:
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
buffer_add(chr);
} else if (isalpha(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_ATOM;
buffer[buffer_index++] = chr;
} else if (isdigit(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_NUM;
buffer[buffer_index++] = chr;
} else {
error("invalid char (STATE_WHITESPACE)");
}
break;
case STATE_OPEN:
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_WHITESPACE;
buffer_add(chr);
} else if (isalpha(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_ATOM;
buffer_add(chr);
} else if (isdigit(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_NUM;
buffer_add(chr);
} else {
error("invalid char (STATE_OPEN)");
}
break;
case STATE_CLOSE:
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_WHITESPACE;
buffer_add(chr);
} else if (isalpha(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_ATOM;
buffer_add(chr);
} else if (isdigit(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_NUM;
buffer_add(chr);
} else {
error("invalid char (STATE_CLOSE)");
}
break;
case STATE_ATOM:
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_WHITESPACE;
buffer_add(chr);
} else if (isalnum(chr)) {
buffer_add(chr);
} else {
error("invalid char (STATE_ATOM)");
}
break;
case STATE_NUM:
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
buffer_add(chr);
} else if (isspace(chr)) {
token_add(state, buffer);
buffer_clean();
state = STATE_WHITESPACE;
buffer_add(chr);
} else if (isdigit(chr)) {
buffer_add(chr);
} else {
error("invalid char (STATE_NUM)");
}
break;
}
}
/**********
* Parser *
**********/