1
0
Fork 0
This commit is contained in:
Alex Kotov 2023-05-04 02:05:11 +04:00
parent 97e2470e6b
commit 01ece4cc9f
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
5 changed files with 98 additions and 50 deletions

View file

@ -3,7 +3,13 @@ all: lisp
CC = gcc
CFLAGS = -Wall -Wextra
OBJS = main.c.o enums.c.o
OBJS = enums.c.o main.c.o tokens.c.o
run: lisp
./lisp
clean:
rm -f lisp $(OBJS)
lisp: $(OBJS)
$(CC) -o $@ $^ $(CFLAGS)

View file

@ -42,10 +42,10 @@ bool
State_to_token_type(const enum State state, enum TokenType *const token_type)
{
switch (state) {
case STATE_OPEN: *token_type = STATE_OPEN; break;
case STATE_CLOSE: *token_type = STATE_CLOSE; break;
case STATE_ID: *token_type = STATE_ID; break;
case STATE_NUM: *token_type = STATE_NUM; break;
case STATE_OPEN: *token_type = TOKEN_OPEN; break;
case STATE_CLOSE: *token_type = TOKEN_CLOSE; break;
case STATE_ID: *token_type = TOKEN_ID; break;
case STATE_NUM: *token_type = TOKEN_NUM; break;
default: return false;
}

61
main.c
View file

@ -1,4 +1,5 @@
#include "enums.h"
#include "tokens.h"
#include <assert.h>
#include <ctype.h>
@ -8,12 +9,6 @@
#include <stdlib.h>
#include <string.h>
struct Token {
struct Token *next;
enum TokenType type;
char *val;
};
struct Object {
enum Type type;
union {
@ -30,7 +25,6 @@ static char buffer[1024];
static size_t buffer_index = 0;
static enum State state = STATE_INIT;
static struct Token *tokens = NULL;
static void error(const char *msg);
@ -47,7 +41,6 @@ static void lex(char chr);
* Parser *
**********/
static void shift_token();
static struct Object *prepare_object(enum Type type);
static void expect(enum TokenType token_type);
@ -77,7 +70,11 @@ int main()
printf("Tokens:\n");
for (const struct Token *token = tokens; token; token = token->next) {
for (
const struct Tokens *token = tokens_top();
token;
token = token->next
) {
printf("%s:%s;\n", TokenType_to_str(token->type), token->val);
}
@ -116,24 +113,7 @@ void token_add(enum State state, char *val)
enum TokenType token_type;
if (!State_to_token_type(state, &token_type)) error("invalid state");
struct Token *token = malloc(sizeof(struct Token));
assert(token);
token->next = NULL;
token->type = token_type;
token->val = malloc(strlen(val) + 1);
assert(token->val);
strcpy(token->val, val);
if (!tokens) {
tokens = token;
} else {
for (struct Token *curr = tokens; curr; curr = curr->next) {
if (!curr->next) {
curr->next = token;
break;
}
}
}
tokens_push(token_type, val);
}
void lex(char chr)
@ -297,13 +277,6 @@ void lex(char chr)
* Parser *
**********/
void shift_token()
{
struct Token *const cur_token = tokens;
tokens = tokens->next;
free(cur_token);
}
struct Object *prepare_object(const enum Type type)
{
struct Object *const object = malloc(sizeof(struct Object));
@ -315,9 +288,7 @@ struct Object *prepare_object(const enum Type type)
void expect(const enum TokenType token_type)
{
if (!tokens) error("no tokens in expect");
if (tokens->type != token_type) error("no expected");
shift_token();
if (!tokens_expect(token_type)) error("expect");
}
struct Object *parse()
@ -327,22 +298,22 @@ struct Object *parse()
struct Object *expr()
{
if (!tokens) error("no tokens");
if (!tokens_top()) error("no tokens");
switch (tokens->type) {
switch (tokens_top()->type) {
case TOKEN_OPEN: return parens();
case TOKEN_ID:
{
struct Object *const object = prepare_object(TYPE_ATOM);
object->s = tokens->val;
shift_token();
object->s = tokens_top()->val;
tokens_pop();
return object;
}
case TOKEN_NUM:
{
struct Object *const object = prepare_object(TYPE_NUMBER);
object->i = atoll(tokens->val);
shift_token();
object->i = atoll(tokens_top()->val);
tokens_pop();
return object;
}
default:
@ -363,11 +334,11 @@ struct Object *parens_part()
{
struct Object *const object = prepare_object(TYPE_PAIR);
if (tokens && tokens->type != TOKEN_CLOSE) {
if (tokens_top() && tokens_top()->type != TOKEN_CLOSE) {
object->a = expr();
}
if (tokens && tokens->type != TOKEN_CLOSE) {
if (tokens_top() && tokens_top()->type != TOKEN_CLOSE) {
object->b = parens_part();
} else {
object->b = NULL;

52
tokens.c Normal file
View file

@ -0,0 +1,52 @@
#include "tokens.h"
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
static struct Tokens *tokens = NULL;
const struct Tokens *tokens_top()
{
return tokens;
}
bool tokens_expect(const enum TokenType token_type)
{
if (!tokens && tokens->type != token_type) return false;
tokens_pop();
return true;
}
void tokens_pop()
{
struct Tokens *const token = tokens;
if (token) {
tokens = token->next;
free(token);
}
}
void tokens_push(const enum TokenType token_type, const char *const val)
{
struct Tokens *token = malloc(sizeof(struct Tokens));
assert(token);
token->next = NULL;
token->type = token_type;
token->val = malloc(strlen(val) + 1);
assert(token->val);
strcpy(token->val, val);
if (!tokens) {
tokens = token;
} else {
for (struct Tokens *curr = tokens; curr; curr = curr->next) {
if (!curr->next) {
curr->next = token;
break;
}
}
}
}

19
tokens.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef __TOKENS_H__
#define __TOKENS_H__
#include "enums.h"
#include <stdbool.h>
struct Tokens {
struct Tokens *next;
enum TokenType type;
char *val;
};
void tokens_push(enum TokenType token_type, const char *val);
void tokens_pop();
bool tokens_expect(enum TokenType token_type);
const struct Tokens *tokens_top();
#endif