Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7744a28a12 | ||
|
|
1d7cc88c22 |
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
BreakBeforeBraces: Allman
|
||||||
|
IndentWidth: 2
|
||||||
|
TabWidth: 2
|
||||||
|
UseTab: Never
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
!/src
|
!/src
|
||||||
|
|
||||||
# Files
|
# Files
|
||||||
|
!/.clang-format
|
||||||
!/.gitignore
|
!/.gitignore
|
||||||
!/CMakeLists.txt
|
!/CMakeLists.txt
|
||||||
!/Makefile
|
!/Makefile
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 4.3)
|
|||||||
project(fz-lang
|
project(fz-lang
|
||||||
LANGUAGES C)
|
LANGUAGES C)
|
||||||
|
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
|
|
||||||
# Compiler
|
# Compiler
|
||||||
|
|||||||
@@ -6,5 +6,4 @@
|
|||||||
// Print AST
|
// Print AST
|
||||||
void fzl_debug_print_ast(fzl_node_t *root);
|
void fzl_debug_print_ast(fzl_node_t *root);
|
||||||
|
|
||||||
#endif//FZL_DEBUG_H
|
#endif // FZL_DEBUG_H
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +1,44 @@
|
|||||||
#ifndef FZL_PARSER_H
|
#ifndef FZL_PARSER_H
|
||||||
#define FZL_PARSER_H
|
#define FZL_PARSER_H
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <compiler/fzl_token.h>
|
|
||||||
#include <compiler/fzl_reader.h>
|
#include <compiler/fzl_reader.h>
|
||||||
|
#include <compiler/fzl_token.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
// AST node type
|
// AST node type
|
||||||
typedef enum {
|
typedef enum
|
||||||
FZL_NODETYPE_BLOCK,
|
{
|
||||||
FZL_NODETYPE_CALL,
|
FZL_NODETYPE_BLOCK,
|
||||||
FZL_NODETYPE_LITERAL,
|
FZL_NODETYPE_CALL,
|
||||||
|
FZL_NODETYPE_LITERAL,
|
||||||
} fzl_nodetype_t;
|
} fzl_nodetype_t;
|
||||||
|
|
||||||
// AST node descriptor
|
// AST node descriptor
|
||||||
typedef struct fzl_node {
|
typedef struct fzl_node
|
||||||
fzl_nodetype_t type;
|
{
|
||||||
fzl_token_t *token;
|
fzl_nodetype_t type;
|
||||||
struct fzl_node *parent;
|
fzl_token_t *token;
|
||||||
struct fzl_node *next;
|
struct fzl_node *parent;
|
||||||
|
struct fzl_node *next;
|
||||||
|
|
||||||
union {
|
union
|
||||||
struct {
|
{
|
||||||
struct fzl_node **entries;
|
struct
|
||||||
size_t entry_count;
|
{
|
||||||
} list;
|
struct fzl_node **entries;
|
||||||
};
|
size_t entry_count;
|
||||||
|
} list;
|
||||||
|
};
|
||||||
} fzl_node_t;
|
} fzl_node_t;
|
||||||
|
|
||||||
// Token sequence parser descriptor
|
// Token sequence parser descriptor
|
||||||
typedef struct {
|
typedef struct
|
||||||
fzl_reader_ll_t *first;
|
{
|
||||||
size_t token_count;
|
fzl_reader_ll_t *first;
|
||||||
|
size_t token_count;
|
||||||
|
|
||||||
fzl_reader_ll_t *cursor;
|
fzl_reader_ll_t *cursor;
|
||||||
fzl_node_t *root;
|
fzl_node_t *root;
|
||||||
} fzl_parser_t;
|
} fzl_parser_t;
|
||||||
|
|
||||||
// Allocate parser
|
// Allocate parser
|
||||||
@@ -49,10 +54,9 @@ int fzl_parse(fzl_parser_t *parser);
|
|||||||
char *fzl_parser_geterror();
|
char *fzl_parser_geterror();
|
||||||
|
|
||||||
// Free node
|
// Free node
|
||||||
void fzl_freenode(fzl_node_t* node);
|
void fzl_freenode(fzl_node_t *node);
|
||||||
|
|
||||||
// Free parser
|
// Free parser
|
||||||
void fzl_freeparser(fzl_parser_t *parser);
|
void fzl_freeparser(fzl_parser_t *parser);
|
||||||
|
|
||||||
#endif//FZL_PARSER_H
|
#endif // FZL_PARSER_H
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,27 @@
|
|||||||
#ifndef FZL_READER_H
|
#ifndef FZL_READER_H
|
||||||
#define FZL_READER_H
|
#define FZL_READER_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <compiler/fzl_token.h>
|
#include <compiler/fzl_token.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// Tokens linked list descriptor
|
// Tokens linked list descriptor
|
||||||
typedef struct fzl_reader_ll {
|
typedef struct fzl_reader_ll
|
||||||
fzl_token_t *token;
|
{
|
||||||
struct fzl_reader_ll *next;
|
fzl_token_t *token;
|
||||||
|
struct fzl_reader_ll *next;
|
||||||
} fzl_reader_ll_t;
|
} fzl_reader_ll_t;
|
||||||
|
|
||||||
// Source reader description
|
// Source reader description
|
||||||
typedef struct {
|
typedef struct
|
||||||
fzl_reader_ll_t *first;
|
{
|
||||||
fzl_reader_ll_t *last;
|
fzl_reader_ll_t *first;
|
||||||
|
fzl_reader_ll_t *last;
|
||||||
|
|
||||||
char *source;
|
char *source;
|
||||||
size_t position;
|
size_t position;
|
||||||
bool at_end;
|
bool at_end;
|
||||||
} fzl_reader_t;
|
} fzl_reader_t;
|
||||||
|
|
||||||
// Allocate new reader
|
// Allocate new reader
|
||||||
@@ -34,5 +36,4 @@ char *fzl_reader_geterror();
|
|||||||
// Free reader
|
// Free reader
|
||||||
void fzl_freereader(fzl_reader_t *reader);
|
void fzl_freereader(fzl_reader_t *reader);
|
||||||
|
|
||||||
#endif//FZL_READER_H
|
#endif // FZL_READER_H
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,36 @@
|
|||||||
#ifndef FZL_TOKEN_H
|
#ifndef FZL_TOKEN_H
|
||||||
#define FZL_TOKEN_H
|
#define FZL_TOKEN_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// Token type
|
// Token type
|
||||||
typedef enum {
|
typedef enum
|
||||||
FZL_TOKTYPE_NAME,
|
{
|
||||||
FZL_TOKTYPE_LPAIR,
|
FZL_TOKTYPE_NAME,
|
||||||
FZL_TOKTYPE_RPAIR,
|
FZL_TOKTYPE_LPAIR,
|
||||||
FZL_TOKTYPE_COMMA,
|
FZL_TOKTYPE_RPAIR,
|
||||||
FZL_TOKTYPE_STR_LITERAL
|
FZL_TOKTYPE_COMMA,
|
||||||
|
FZL_TOKTYPE_STR_LITERAL
|
||||||
} fzl_toktype_t;
|
} fzl_toktype_t;
|
||||||
|
|
||||||
// Token descriptor
|
// Token descriptor
|
||||||
typedef struct {
|
typedef struct
|
||||||
fzl_toktype_t type;
|
{
|
||||||
uint16_t i0;
|
fzl_toktype_t type;
|
||||||
uint16_t i1;
|
uint16_t i0;
|
||||||
bool store_value;
|
uint16_t i1;
|
||||||
void *value;
|
bool store_value;
|
||||||
uint16_t value_sz;
|
void *value;
|
||||||
|
uint16_t value_sz;
|
||||||
} fzl_token_t;
|
} fzl_token_t;
|
||||||
|
|
||||||
// Allocate new token
|
// Allocate new token
|
||||||
fzl_token_t *fzl_mktoken(
|
fzl_token_t *fzl_mktoken(const fzl_toktype_t type, uint16_t from, uint16_t to,
|
||||||
const fzl_toktype_t type, uint16_t from, uint16_t to,
|
void *value, size_t value_sz);
|
||||||
void *value, size_t value_sz);
|
|
||||||
|
|
||||||
// Free token and its contents
|
// Free token and its contents
|
||||||
void fzl_freetoken(fzl_token_t *token);
|
void fzl_freetoken(fzl_token_t *token);
|
||||||
|
|
||||||
#endif//FZL_TOKEN_H
|
#endif // FZL_TOKEN_H
|
||||||
|
|
||||||
|
|||||||
+58
-57
@@ -1,82 +1,83 @@
|
|||||||
#include <compiler/fzl_debug.h>
|
#include <compiler/fzl_debug.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
size_t print_level(char *buf, int level)
|
size_t print_level(char *buf, int level)
|
||||||
{
|
{
|
||||||
int lvl = 0;
|
int lvl = 0;
|
||||||
while (lvl < level)
|
while (lvl < level)
|
||||||
{
|
{
|
||||||
buf[lvl] = '-';
|
buf[lvl] = '-';
|
||||||
lvl++;
|
lvl++;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[lvl] = '>';
|
buf[lvl] = '>';
|
||||||
return strlen(buf);
|
return strlen(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_node(fzl_node_t *node, int level)
|
void print_node(fzl_node_t *node, int level)
|
||||||
{
|
{
|
||||||
char levelbuf[32];
|
char levelbuf[32];
|
||||||
char printbuf[256];
|
char printbuf[256];
|
||||||
memset(levelbuf, 0, sizeof(levelbuf));
|
memset(levelbuf, 0, sizeof(levelbuf));
|
||||||
memset(printbuf, 0, sizeof(printbuf));
|
memset(printbuf, 0, sizeof(printbuf));
|
||||||
|
|
||||||
if (!node) return;
|
if (!node)
|
||||||
|
return;
|
||||||
size_t lvllen = print_level(levelbuf, level);
|
|
||||||
strcpy(printbuf, levelbuf);
|
|
||||||
|
|
||||||
switch (node->type)
|
size_t lvllen = print_level(levelbuf, level);
|
||||||
{
|
strcpy(printbuf, levelbuf);
|
||||||
case FZL_NODETYPE_CALL:
|
|
||||||
if (node->list.entry_count > 0)
|
|
||||||
{
|
|
||||||
printf("%s Call fn '%s' with args:\n", levelbuf, (char*)node->token->value);
|
|
||||||
for (size_t i = 0; i < node->list.entry_count; i++)
|
|
||||||
print_node(node->list.entries[i], level + 1);
|
|
||||||
}
|
|
||||||
else printf("%s Call fn '%s' w/o args\n", levelbuf, (char*)node->token->value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FZL_NODETYPE_LITERAL:
|
switch (node->type)
|
||||||
printf("%s Literal '%s'\n",
|
{
|
||||||
levelbuf,
|
case FZL_NODETYPE_CALL:
|
||||||
(char*)node->token->value);
|
if (node->list.entry_count > 0)
|
||||||
break;
|
{
|
||||||
|
printf("%s Call fn '%s' with args:\n", levelbuf,
|
||||||
|
(char *)node->token->value);
|
||||||
|
for (size_t i = 0; i < node->list.entry_count; i++)
|
||||||
|
print_node(node->list.entries[i], level + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("%s Call fn '%s' w/o args\n", levelbuf,
|
||||||
|
(char *)node->token->value);
|
||||||
|
break;
|
||||||
|
|
||||||
case FZL_NODETYPE_BLOCK:
|
case FZL_NODETYPE_LITERAL:
|
||||||
printf("%s Block: ", levelbuf);
|
printf("%s Literal '%s'\n", levelbuf, (char *)node->token->value);
|
||||||
|
break;
|
||||||
|
|
||||||
if (node->list.entry_count < 1)
|
case FZL_NODETYPE_BLOCK:
|
||||||
{
|
printf("%s Block: ", levelbuf);
|
||||||
printf("<empty>\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
for (size_t i = 0; i < node->list.entry_count; i++)
|
|
||||||
print_node(node->list.entries[i], level + 1);
|
|
||||||
|
|
||||||
break;
|
if (node->list.entry_count < 1)
|
||||||
|
{
|
||||||
|
printf("<empty>\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
printf("\n");
|
||||||
printf("%s Secure node\n", levelbuf);
|
for (size_t i = 0; i < node->list.entry_count; i++)
|
||||||
}
|
print_node(node->list.entries[i], level + 1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("%s Secure node\n", levelbuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fzl_debug_print_ast(fzl_node_t *root)
|
void fzl_debug_print_ast(fzl_node_t *root)
|
||||||
{
|
{
|
||||||
printf("> AST tree:\n");
|
printf("> AST tree:\n");
|
||||||
|
|
||||||
fzl_node_t *curr = root;
|
fzl_node_t *curr = root;
|
||||||
while (curr != NULL)
|
while (curr != NULL)
|
||||||
{
|
{
|
||||||
print_node(curr, 2);
|
print_node(curr, 2);
|
||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("-> FINISH\n");
|
printf("-> FINISH\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+131
-122
@@ -1,25 +1,27 @@
|
|||||||
#include <compiler/fzl_parser.h>
|
#include <compiler/fzl_parser.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
char last_err[256];
|
char last_err[256];
|
||||||
|
|
||||||
fzl_parser_t *fzl_mkparser(fzl_reader_ll_t *first)
|
fzl_parser_t *fzl_mkparser(fzl_reader_ll_t *first)
|
||||||
{
|
{
|
||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
snprintf(last_err, sizeof(last_err), "token is null");
|
snprintf(last_err, sizeof(last_err), "token is null");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fzl_parser_t *parser = malloc(sizeof(fzl_parser_t));
|
fzl_parser_t *parser = malloc(sizeof(fzl_parser_t));
|
||||||
if (!parser) return NULL;
|
if (!parser)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
parser->root = NULL;
|
parser->root = NULL;
|
||||||
parser->cursor = first->next;
|
parser->cursor = first->next;
|
||||||
if (!parser->cursor) return NULL;
|
if (!parser->cursor)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Parse zone ---
|
// --- Parse zone ---
|
||||||
@@ -27,56 +29,61 @@ fzl_parser_t *fzl_mkparser(fzl_reader_ll_t *first)
|
|||||||
// Make a new node
|
// Make a new node
|
||||||
fzl_node_t *fzl_mknode(fzl_nodetype_t type, fzl_token_t *token)
|
fzl_node_t *fzl_mknode(fzl_nodetype_t type, fzl_token_t *token)
|
||||||
{
|
{
|
||||||
fzl_node_t *node = malloc(sizeof(fzl_node_t));
|
fzl_node_t *node = malloc(sizeof(fzl_node_t));
|
||||||
|
|
||||||
if (!node) return NULL;
|
if (!node)
|
||||||
node->type = type;
|
return NULL;
|
||||||
node->token = token;
|
node->type = type;
|
||||||
node->parent = NULL;
|
node->token = token;
|
||||||
node->next = NULL;
|
node->parent = NULL;
|
||||||
|
node->next = NULL;
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get token at cursor
|
// Get token at cursor
|
||||||
static fzl_token_t *peek(fzl_parser_t *parser)
|
static fzl_token_t *peek(fzl_parser_t *parser)
|
||||||
{
|
{
|
||||||
if (!parser->cursor) return NULL;
|
if (!parser->cursor)
|
||||||
return parser->cursor->token;
|
return NULL;
|
||||||
|
return parser->cursor->token;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get token at (cursor + 1)
|
// Get token at (cursor + 1)
|
||||||
static fzl_token_t *next(fzl_parser_t *parser)
|
static fzl_token_t *next(fzl_parser_t *parser)
|
||||||
{
|
{
|
||||||
if (!parser->cursor) return NULL;
|
if (!parser->cursor)
|
||||||
|
return NULL;
|
||||||
fzl_reader_ll_t *next = parser->cursor->next;
|
|
||||||
if (!next) return NULL;
|
|
||||||
|
|
||||||
return next->token;
|
fzl_reader_ll_t *next = parser->cursor->next;
|
||||||
|
if (!next)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return next->token;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consume token at cursor and move to the next
|
// Consume token at cursor and move to the next
|
||||||
static fzl_token_t *consume(fzl_parser_t *parser)
|
static fzl_token_t *consume(fzl_parser_t *parser)
|
||||||
{
|
{
|
||||||
if (!parser->cursor) return NULL;
|
if (!parser->cursor)
|
||||||
fzl_token_t *tok = parser->cursor->token;
|
return NULL;
|
||||||
parser->cursor = parser->cursor->next;
|
fzl_token_t *tok = parser->cursor->token;
|
||||||
return tok;
|
parser->cursor = parser->cursor->next;
|
||||||
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse primary
|
// Parse primary
|
||||||
fzl_node_t *parse_primary(fzl_parser_t *parser)
|
fzl_node_t *parse_primary(fzl_parser_t *parser)
|
||||||
{
|
{
|
||||||
if (peek(parser) && peek(parser)->type == FZL_TOKTYPE_STR_LITERAL)
|
if (peek(parser) && peek(parser)->type == FZL_TOKTYPE_STR_LITERAL)
|
||||||
{
|
{
|
||||||
fzl_token_t *tok = consume(parser);
|
fzl_token_t *tok = consume(parser);
|
||||||
return fzl_mknode(FZL_NODETYPE_LITERAL, tok);
|
return fzl_mknode(FZL_NODETYPE_LITERAL, tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(last_err, sizeof(last_err),
|
snprintf(last_err, sizeof(last_err), "failed to parse primary at %d",
|
||||||
"failed to parse primary at %d", peek(parser)->i0);
|
peek(parser)->i0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fzl_node_t *parse_expression(fzl_parser_t *parser, int precedence);
|
fzl_node_t *parse_expression(fzl_parser_t *parser, int precedence);
|
||||||
@@ -84,131 +91,133 @@ fzl_node_t *parse_expression(fzl_parser_t *parser, int precedence);
|
|||||||
// Parse call expression
|
// Parse call expression
|
||||||
fzl_node_t *parse_call(fzl_parser_t *parser)
|
fzl_node_t *parse_call(fzl_parser_t *parser)
|
||||||
{
|
{
|
||||||
fzl_token_t *tok = consume(parser); // <NAME>
|
fzl_token_t *tok = consume(parser); // <NAME>
|
||||||
consume(parser); // (
|
consume(parser); // (
|
||||||
|
|
||||||
fzl_node_t *node = fzl_mknode(FZL_NODETYPE_CALL, tok);
|
|
||||||
node->list.entry_count = 0;
|
|
||||||
|
|
||||||
size_t capacity = 4;
|
fzl_node_t *node = fzl_mknode(FZL_NODETYPE_CALL, tok);
|
||||||
node->list.entries = malloc(capacity * sizeof(fzl_node_t*));
|
node->list.entry_count = 0;
|
||||||
node->list.entry_count = 0;
|
|
||||||
|
|
||||||
if (peek(parser) && peek(parser)->type == FZL_TOKTYPE_RPAIR)
|
size_t capacity = 4;
|
||||||
{
|
node->list.entries = malloc(capacity * sizeof(fzl_node_t *));
|
||||||
consume(parser);
|
node->list.entry_count = 0;
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (peek(parser) && peek(parser)->type != FZL_TOKTYPE_RPAIR)
|
if (peek(parser) && peek(parser)->type == FZL_TOKTYPE_RPAIR)
|
||||||
{
|
{
|
||||||
fzl_node_t *arg = parse_expression(parser, 0);
|
consume(parser);
|
||||||
if (!arg) return NULL;
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
if (node->list.entry_count == capacity)
|
while (peek(parser) && peek(parser)->type != FZL_TOKTYPE_RPAIR)
|
||||||
{
|
{
|
||||||
capacity *= 2;
|
fzl_node_t *arg = parse_expression(parser, 0);
|
||||||
node->list.entries = realloc(node->list.entries, capacity * sizeof(fzl_node_t*));
|
if (!arg)
|
||||||
}
|
return NULL;
|
||||||
|
|
||||||
node->list.entries[node->list.entry_count++] = arg;
|
if (node->list.entry_count == capacity)
|
||||||
|
{
|
||||||
|
capacity *= 2;
|
||||||
|
node->list.entries =
|
||||||
|
realloc(node->list.entries, capacity * sizeof(fzl_node_t *));
|
||||||
|
}
|
||||||
|
|
||||||
if (peek(parser) && peek(parser)->type == FZL_TOKTYPE_COMMA)
|
node->list.entries[node->list.entry_count++] = arg;
|
||||||
consume(parser);
|
|
||||||
else if (peek(parser) && peek(parser)->type != FZL_TOKTYPE_RPAIR)
|
|
||||||
{
|
|
||||||
snprintf(last_err, sizeof(last_err), "expected ',' or ')' after arg list");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
consume(parser);
|
if (peek(parser) && peek(parser)->type == FZL_TOKTYPE_COMMA)
|
||||||
return node;
|
consume(parser);
|
||||||
|
else if (peek(parser) && peek(parser)->type != FZL_TOKTYPE_RPAIR)
|
||||||
|
{
|
||||||
|
snprintf(last_err, sizeof(last_err),
|
||||||
|
"expected ',' or ')' after arg list");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
consume(parser);
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expression parsing
|
// Expression parsing
|
||||||
fzl_node_t *parse_expression(fzl_parser_t *parser, int precedence)
|
fzl_node_t *parse_expression(fzl_parser_t *parser, int precedence)
|
||||||
{
|
{
|
||||||
if (peek(parser) && peek(parser)->type == FZL_TOKTYPE_NAME)
|
if (peek(parser) && peek(parser)->type == FZL_TOKTYPE_NAME)
|
||||||
{
|
{
|
||||||
if (next(parser) && next(parser)->type == FZL_TOKTYPE_LPAIR)
|
if (next(parser) && next(parser)->type == FZL_TOKTYPE_LPAIR)
|
||||||
return parse_call(parser);
|
return parse_call(parser);
|
||||||
}
|
}
|
||||||
else if (peek(parser) && peek(parser)->type == FZL_TOKTYPE_STR_LITERAL)
|
else if (peek(parser) && peek(parser)->type == FZL_TOKTYPE_STR_LITERAL)
|
||||||
return parse_primary(parser);
|
return parse_primary(parser);
|
||||||
|
|
||||||
snprintf(last_err, sizeof(last_err),
|
snprintf(last_err, sizeof(last_err), "failed to parse expression at %d",
|
||||||
"failed to parse expression at %d",
|
peek(parser)->i0);
|
||||||
peek(parser)->i0);
|
return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statement parsing
|
// Statement parsing
|
||||||
fzl_node_t *parse_statement(fzl_parser_t *parser)
|
fzl_node_t *parse_statement(fzl_parser_t *parser)
|
||||||
{
|
{
|
||||||
return parse_expression(parser, 0);
|
return parse_expression(parser, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal parsing entry point
|
// Internal parsing entry point
|
||||||
fzl_node_t *parse_program(fzl_parser_t *parser)
|
fzl_node_t *parse_program(fzl_parser_t *parser)
|
||||||
{
|
{
|
||||||
fzl_node_t *first = NULL;
|
fzl_node_t *first = NULL;
|
||||||
fzl_node_t *last = NULL;
|
fzl_node_t *last = NULL;
|
||||||
fzl_node_t *node = NULL;
|
fzl_node_t *node = NULL;
|
||||||
while (peek(parser) != NULL)
|
while (peek(parser) != NULL)
|
||||||
{
|
{
|
||||||
node = parse_statement(parser);
|
node = parse_statement(parser);
|
||||||
if (!node) return NULL;
|
if (!node)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (!last)
|
if (!last)
|
||||||
{
|
{
|
||||||
first = node;
|
first = node;
|
||||||
last = node;
|
last = node;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
last->next = node;
|
last->next = node;
|
||||||
last = node;
|
last = node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
snprintf(last_err, sizeof(last_err), "empty ;(");
|
snprintf(last_err, sizeof(last_err), "empty ;(");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Parse tokens and build AST
|
// Parse tokens and build AST
|
||||||
int fzl_parse(fzl_parser_t *parser)
|
int fzl_parse(fzl_parser_t *parser)
|
||||||
{
|
{
|
||||||
fzl_node_t *ast = parse_program(parser);
|
fzl_node_t *ast = parse_program(parser);
|
||||||
if (!ast) return -1;
|
if (!ast)
|
||||||
|
return -1;
|
||||||
|
|
||||||
parser->root = ast;
|
parser->root = ast;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Parse zone end ---
|
// --- Parse zone end ---
|
||||||
|
|
||||||
char *fzl_parser_geterror()
|
char *fzl_parser_geterror() { return last_err; }
|
||||||
{
|
|
||||||
return last_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fzl_freenode(fzl_node_t *node)
|
void fzl_freenode(fzl_node_t *node)
|
||||||
{
|
{
|
||||||
if (!node) return;
|
if (!node)
|
||||||
if (node->token) fzl_freetoken(node->token);
|
return;
|
||||||
free(node);
|
if (node->token)
|
||||||
|
fzl_freetoken(node->token);
|
||||||
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fzl_freeparser(fzl_parser_t *parser)
|
void fzl_freeparser(fzl_parser_t *parser)
|
||||||
{
|
{
|
||||||
if (!parser) return;
|
if (!parser)
|
||||||
free(parser);
|
return;
|
||||||
|
free(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+124
-143
@@ -8,18 +8,18 @@ static char last_err[256] = {0};
|
|||||||
|
|
||||||
fzl_reader_t *fzl_mkreader(char *source)
|
fzl_reader_t *fzl_mkreader(char *source)
|
||||||
{
|
{
|
||||||
fzl_reader_ll_t *first_node = malloc(sizeof(fzl_reader_ll_t));
|
fzl_reader_ll_t *first_node = malloc(sizeof(fzl_reader_ll_t));
|
||||||
first_node->token = NULL;
|
first_node->token = NULL;
|
||||||
first_node->next = NULL;
|
first_node->next = NULL;
|
||||||
|
|
||||||
fzl_reader_t *reader = malloc(sizeof(fzl_reader_t));
|
fzl_reader_t *reader = malloc(sizeof(fzl_reader_t));
|
||||||
reader->first = first_node;
|
reader->first = first_node;
|
||||||
reader->last = first_node;
|
reader->last = first_node;
|
||||||
reader->source = source;
|
reader->source = source;
|
||||||
reader->position = 0;
|
reader->position = 0;
|
||||||
reader->at_end = true;
|
reader->at_end = true;
|
||||||
|
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Read zone ---
|
// --- Read zone ---
|
||||||
@@ -27,176 +27,157 @@ fzl_reader_t *fzl_mkreader(char *source)
|
|||||||
// Try parse name
|
// Try parse name
|
||||||
fzl_token_t *parse_name(fzl_reader_t *reader)
|
fzl_token_t *parse_name(fzl_reader_t *reader)
|
||||||
{
|
{
|
||||||
size_t lpos = reader->position;
|
size_t lpos = reader->position;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
lpos++;
|
lpos++;
|
||||||
size++;
|
size++;
|
||||||
}
|
} while ((reader->source[lpos] >= 'A' && reader->source[lpos] <= 'Z') ||
|
||||||
while ((reader->source[lpos] >= 'A' && reader->source[lpos] <= 'Z')
|
(reader->source[lpos] >= 'a' && reader->source[lpos] <= 'z'));
|
||||||
|| (reader->source[lpos] >= 'a' && reader->source[lpos] <= 'z'));
|
|
||||||
|
|
||||||
char *value = malloc(size);
|
char *value = malloc(size);
|
||||||
memcpy(value, reader->source + reader->position, size);
|
memcpy(value, reader->source + reader->position, size);
|
||||||
|
|
||||||
size_t start = reader->position;
|
size_t start = reader->position;
|
||||||
reader->position += size;
|
reader->position += size;
|
||||||
|
|
||||||
fzl_token_t *tok = fzl_mktoken(
|
fzl_token_t *tok =
|
||||||
FZL_TOKTYPE_NAME,
|
fzl_mktoken(FZL_TOKTYPE_NAME, start, reader->position - 1, value, size);
|
||||||
start,
|
free(value);
|
||||||
reader->position - 1,
|
|
||||||
value,
|
|
||||||
size
|
|
||||||
);
|
|
||||||
free(value);
|
|
||||||
|
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try parse string literal
|
// Try parse string literal
|
||||||
fzl_token_t *parse_string_literal(fzl_reader_t *reader)
|
fzl_token_t *parse_string_literal(fzl_reader_t *reader)
|
||||||
{
|
{
|
||||||
size_t lpos = reader->position;
|
size_t lpos = reader->position;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
|
||||||
if (reader->source[lpos] != '\'' && reader->source[lpos] != '"')
|
if (reader->source[lpos] != '\'' && reader->source[lpos] != '"')
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
char open_symbol = reader->source[lpos];
|
char open_symbol = reader->source[lpos];
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
lpos++;
|
lpos++;
|
||||||
size++;
|
size++;
|
||||||
}
|
} while (reader->source[lpos] != open_symbol);
|
||||||
while (reader->source[lpos] != open_symbol);
|
size++;
|
||||||
size++;
|
|
||||||
|
|
||||||
if (size == 2)
|
if (size == 2)
|
||||||
{
|
{
|
||||||
fzl_token_t *tok = fzl_mktoken(
|
fzl_token_t *tok = fzl_mktoken(FZL_TOKTYPE_STR_LITERAL, reader->position,
|
||||||
FZL_TOKTYPE_STR_LITERAL,
|
reader->position + 1, "", 0);
|
||||||
reader->position,
|
return tok;
|
||||||
reader->position + 1,
|
}
|
||||||
"",
|
|
||||||
0
|
|
||||||
);
|
|
||||||
return tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *value = malloc(size - 2);
|
char *value = malloc(size - 2);
|
||||||
memcpy(value, reader->source + reader->position + 1, size - 2);
|
memcpy(value, reader->source + reader->position + 1, size - 2);
|
||||||
fzl_token_t *tok = fzl_mktoken(
|
fzl_token_t *tok = fzl_mktoken(FZL_TOKTYPE_STR_LITERAL, reader->position,
|
||||||
FZL_TOKTYPE_STR_LITERAL,
|
lpos, value, size - 2);
|
||||||
reader->position,
|
free(value);
|
||||||
lpos,
|
|
||||||
value,
|
|
||||||
size - 2
|
|
||||||
);
|
|
||||||
free(value);
|
|
||||||
|
|
||||||
reader->position += size;
|
reader->position += size;
|
||||||
|
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fzl_read(fzl_reader_t *reader)
|
int fzl_read(fzl_reader_t *reader)
|
||||||
{
|
{
|
||||||
const size_t len = strlen(reader->source);
|
const size_t len = strlen(reader->source);
|
||||||
if (reader->position >= len) return 0;
|
if (reader->position >= len)
|
||||||
|
return 0;
|
||||||
do {
|
|
||||||
size_t p = reader->position;
|
|
||||||
fzl_token_t *token;
|
|
||||||
char curr = reader->source[p];
|
|
||||||
|
|
||||||
if (curr == '\n' || curr == ' ' || curr == '\r')
|
do
|
||||||
{
|
{
|
||||||
reader->position++;
|
size_t p = reader->position;
|
||||||
continue;
|
fzl_token_t *token;
|
||||||
}
|
char curr = reader->source[p];
|
||||||
|
|
||||||
if (curr == '\'' || curr == '"')
|
if (curr == '\n' || curr == ' ' || curr == '\r')
|
||||||
token = parse_string_literal(reader);
|
{
|
||||||
else if (curr == '(')
|
reader->position++;
|
||||||
{
|
continue;
|
||||||
token = fzl_mktoken(
|
}
|
||||||
FZL_TOKTYPE_LPAIR,
|
|
||||||
p, p, NULL, 0);
|
|
||||||
reader->position++;
|
|
||||||
}
|
|
||||||
else if (curr == ')')
|
|
||||||
{
|
|
||||||
token = fzl_mktoken(
|
|
||||||
FZL_TOKTYPE_RPAIR,
|
|
||||||
p, p, NULL, 0);
|
|
||||||
reader->position++;
|
|
||||||
}
|
|
||||||
else if (curr >= 'A' && curr <= 'Z' ||
|
|
||||||
curr >= 'a' && curr <= 'z')
|
|
||||||
token = parse_name(reader);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(last_err, "undefined token '%c'", curr);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!token)
|
if (curr == '\'' || curr == '"')
|
||||||
{
|
token = parse_string_literal(reader);
|
||||||
size_t line = 1, linepos = 1;
|
else if (curr == '(')
|
||||||
for (size_t i = 0; i < p; i++)
|
{
|
||||||
{
|
token = fzl_mktoken(FZL_TOKTYPE_LPAIR, p, p, NULL, 0);
|
||||||
char sym = reader->source[i];
|
reader->position++;
|
||||||
if (sym == '\n')
|
}
|
||||||
{
|
else if (curr == ')')
|
||||||
linepos = 1;
|
{
|
||||||
line++;
|
token = fzl_mktoken(FZL_TOKTYPE_RPAIR, p, p, NULL, 0);
|
||||||
} else linepos++;
|
reader->position++;
|
||||||
}
|
}
|
||||||
|
else if (curr >= 'A' && curr <= 'Z' || curr >= 'a' && curr <= 'z')
|
||||||
|
token = parse_name(reader);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(last_err, "undefined token '%c'", curr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(last_err, "error parsing token (position %ld of line %ld)", line, linepos);
|
if (!token)
|
||||||
return -1;
|
{
|
||||||
}
|
size_t line = 1, linepos = 1;
|
||||||
|
for (size_t i = 0; i < p; i++)
|
||||||
|
{
|
||||||
|
char sym = reader->source[i];
|
||||||
|
if (sym == '\n')
|
||||||
|
{
|
||||||
|
linepos = 1;
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
linepos++;
|
||||||
|
}
|
||||||
|
|
||||||
fzl_reader_ll_t *tok_node = malloc(sizeof(fzl_reader_ll_t));
|
sprintf(last_err, "error parsing token (position %ld of line %ld)", line,
|
||||||
tok_node->token = token;
|
linepos);
|
||||||
|
return -1;
|
||||||
reader->last->next = tok_node;
|
}
|
||||||
reader->last = tok_node;
|
|
||||||
} while (reader->position < len);
|
|
||||||
|
|
||||||
reader->at_end = true;
|
fzl_reader_ll_t *tok_node = malloc(sizeof(fzl_reader_ll_t));
|
||||||
return 0;
|
tok_node->token = token;
|
||||||
|
|
||||||
|
reader->last->next = tok_node;
|
||||||
|
reader->last = tok_node;
|
||||||
|
} while (reader->position < len);
|
||||||
|
|
||||||
|
reader->at_end = true;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Read zone end ---
|
// --- Read zone end ---
|
||||||
|
|
||||||
char *fzl_reader_geterror()
|
char *fzl_reader_geterror() { return last_err; }
|
||||||
{
|
|
||||||
return last_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_node_and_next(fzl_reader_ll_t *node)
|
void free_node_and_next(fzl_reader_ll_t *node)
|
||||||
{
|
{
|
||||||
if (!node) return;
|
if (!node)
|
||||||
if (node->next)
|
return;
|
||||||
free_node_and_next(node->next);
|
if (node->next)
|
||||||
|
free_node_and_next(node->next);
|
||||||
if (node->token)
|
|
||||||
fzl_freetoken(node->token);
|
|
||||||
|
|
||||||
free(node);
|
if (node->token)
|
||||||
|
fzl_freetoken(node->token);
|
||||||
|
|
||||||
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fzl_freereader(fzl_reader_t *reader)
|
void fzl_freereader(fzl_reader_t *reader)
|
||||||
{
|
{
|
||||||
if (!reader) return;
|
if (!reader)
|
||||||
if (reader->first)
|
return;
|
||||||
free_node_and_next(reader->first);
|
if (reader->first)
|
||||||
|
free_node_and_next(reader->first);
|
||||||
free(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
free(reader);
|
||||||
|
}
|
||||||
|
|||||||
+15
-16
@@ -2,28 +2,27 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
fzl_token_t *fzl_mktoken(
|
fzl_token_t *fzl_mktoken(const fzl_toktype_t type, uint16_t from, uint16_t to,
|
||||||
const fzl_toktype_t type, uint16_t from, uint16_t to,
|
void *value, size_t value_len)
|
||||||
void *value, size_t value_len)
|
|
||||||
{
|
{
|
||||||
void *valholder = malloc(value_len);
|
void *valholder = malloc(value_len);
|
||||||
memcpy(valholder, value, value_len);
|
memcpy(valholder, value, value_len);
|
||||||
|
|
||||||
fzl_token_t *token = malloc(sizeof(fzl_token_t));
|
fzl_token_t *token = malloc(sizeof(fzl_token_t));
|
||||||
token->type = type;
|
token->type = type;
|
||||||
token->i0 = from;
|
token->i0 = from;
|
||||||
token->i1 = to;
|
token->i1 = to;
|
||||||
token->store_value = value_len > 0;
|
token->store_value = value_len > 0;
|
||||||
token->value = valholder;
|
token->value = valholder;
|
||||||
token->value_sz = value_len;
|
token->value_sz = value_len;
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free allocated token
|
// Free allocated token
|
||||||
void fzl_freetoken(fzl_token_t *tok)
|
void fzl_freetoken(fzl_token_t *tok)
|
||||||
{
|
{
|
||||||
if (tok->store_value) free(tok->value);
|
if (tok->store_value)
|
||||||
free(tok);
|
free(tok->value);
|
||||||
|
free(tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+161
-75
@@ -1,80 +1,166 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <compiler/fzl_reader.h>
|
|
||||||
#include <compiler/fzl_parser.h>
|
|
||||||
#include <compiler/fzl_debug.h>
|
#include <compiler/fzl_debug.h>
|
||||||
|
#include <compiler/fzl_parser.h>
|
||||||
|
#include <compiler/fzl_reader.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
// Build arguments setup descriptor
|
||||||
if (argc < 2)
|
typedef struct
|
||||||
{
|
{
|
||||||
printf("No files provided >:(\n");
|
char *filepath;
|
||||||
return -1;
|
bool verbose;
|
||||||
}
|
bool help;
|
||||||
else if (argc > 2)
|
} build_args_t;
|
||||||
{
|
|
||||||
printf("warn: flags are not supported yet\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("> analyze\n-> reading file...");
|
// Print command usage hint
|
||||||
|
void print_usage()
|
||||||
char source[8192];
|
{
|
||||||
FILE *fd = fopen(argv[argc - 1], "r");
|
printf("Usage: fzc [flags] <file path>\n");
|
||||||
if (!fd)
|
printf("Flags:\n");
|
||||||
{
|
printf("\t-v\t--verbose\tdisplay debug information\n");
|
||||||
printf("failed to open file '%s'\n", argv[argc-1]);
|
printf("\t-h\t--help\t\tprint usage hint (which you're looking at)\n");
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(fd, 0L, SEEK_END);
|
|
||||||
size_t fsz = ftell(fd);
|
|
||||||
rewind(fd);
|
|
||||||
|
|
||||||
fread(source, fsz, 1, fd);
|
|
||||||
fclose(fd);
|
|
||||||
printf("ok!\n");
|
|
||||||
|
|
||||||
printf("-> tokenizing...");
|
|
||||||
fzl_reader_t *rd = fzl_mkreader(source);
|
|
||||||
int result = fzl_read(rd);
|
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
printf("error: %s\n", fzl_reader_geterror());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("ok!\n");
|
|
||||||
|
|
||||||
fzl_reader_ll_t *entry = rd->first;
|
|
||||||
printf("--> structure: ");
|
|
||||||
while (entry)
|
|
||||||
{
|
|
||||||
if (entry->token)
|
|
||||||
{
|
|
||||||
if (entry->token->store_value)
|
|
||||||
printf("<TOK:%d:%s>", entry->token->type, (char*)entry->token->value);
|
|
||||||
else
|
|
||||||
printf("<TOK:%d>", entry->token->type);
|
|
||||||
}
|
|
||||||
|
|
||||||
entry = entry->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
printf("-> parsing...");
|
|
||||||
fzl_parser_t *parser = fzl_mkparser(rd->first);
|
|
||||||
result = fzl_parse(parser);
|
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
printf("error: %s\n", fzl_parser_geterror());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("ok!\n");
|
|
||||||
fzl_debug_print_ast(parser->root);
|
|
||||||
|
|
||||||
fzl_freereader(rd);
|
|
||||||
fzl_freeparser(parser);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read the arguments and build `build_args_t` struct
|
||||||
|
build_args_t *getargs(int argc, char **argv)
|
||||||
|
{
|
||||||
|
build_args_t *args = malloc(sizeof(build_args_t));
|
||||||
|
if (!args)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
args->filepath = NULL;
|
||||||
|
args->verbose = false;
|
||||||
|
args->help = false;
|
||||||
|
|
||||||
|
size_t args_total = 0;
|
||||||
|
if (argc > 2)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (argv[i][0] != '-')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
args_total++;
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
|
||||||
|
{
|
||||||
|
args->help = true;
|
||||||
|
}
|
||||||
|
else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0)
|
||||||
|
{
|
||||||
|
args->verbose = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Error: unknown argument '%s'\n", argv[i]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc - 1 - args_total < 1)
|
||||||
|
{
|
||||||
|
printf("Error: source code file is not specified.\n");
|
||||||
|
print_usage();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argv[argc - 1][0] == '-')
|
||||||
|
{
|
||||||
|
printf("Error: last argument MUST be a path to file.\n");
|
||||||
|
printf("Write 'fzc --help' to read help\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
args->filepath = argv[argc - 1];
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
build_args_t *args = getargs(argc, argv);
|
||||||
|
if (args == NULL)
|
||||||
|
return -1;
|
||||||
|
else if (args->help)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (args->verbose)
|
||||||
|
printf("> analyze\n-> reading file...");
|
||||||
|
|
||||||
|
char source[8192];
|
||||||
|
FILE *fd = fopen(args->filepath, "r");
|
||||||
|
if (!fd)
|
||||||
|
{
|
||||||
|
printf("Error: failed to open file '%s'\n", args->filepath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(fd, 0L, SEEK_END);
|
||||||
|
size_t fsz = ftell(fd);
|
||||||
|
rewind(fd);
|
||||||
|
|
||||||
|
fread(source, fsz, 1, fd);
|
||||||
|
fclose(fd);
|
||||||
|
if (args->verbose)
|
||||||
|
{
|
||||||
|
printf("ok!\n");
|
||||||
|
printf("-> tokenizing...");
|
||||||
|
}
|
||||||
|
|
||||||
|
fzl_reader_t *rd = fzl_mkreader(source);
|
||||||
|
int result = fzl_read(rd);
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
printf("error: %s\n", fzl_reader_geterror());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->verbose)
|
||||||
|
printf("ok!\n");
|
||||||
|
|
||||||
|
fzl_reader_ll_t *entry = rd->first;
|
||||||
|
|
||||||
|
if (args->verbose)
|
||||||
|
{
|
||||||
|
printf("--> structure: ");
|
||||||
|
while (entry)
|
||||||
|
{
|
||||||
|
if (entry->token)
|
||||||
|
{
|
||||||
|
if (entry->token->store_value)
|
||||||
|
printf("<TOK:%d:%s>", entry->token->type,
|
||||||
|
(char *)entry->token->value);
|
||||||
|
else
|
||||||
|
printf("<TOK:%d>", entry->token->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = entry->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
printf("-> parsing...");
|
||||||
|
}
|
||||||
|
|
||||||
|
fzl_parser_t *parser = fzl_mkparser(rd->first);
|
||||||
|
result = fzl_parse(parser);
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
printf("Error: %s\n", fzl_parser_geterror());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->verbose)
|
||||||
|
{
|
||||||
|
printf("ok!\n");
|
||||||
|
fzl_debug_print_ast(parser->root);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(args);
|
||||||
|
fzl_freereader(rd);
|
||||||
|
fzl_freeparser(parser);
|
||||||
|
|
||||||
|
printf("done.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user