Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

lexer: replace FILE stream with char array

commit c9c5653910239557b6fb92a66c02d308cb4574e6 1 parent 2e6a3ee
TJ Holowaychuk tj authored
1  .gitignore
View
@@ -4,3 +4,4 @@ luna
testing
.DS_Store
test_runner
+test.luna
19 src/lexer.c
View
@@ -12,23 +12,23 @@
#include "lexer.h"
/*
- * Next char in the stream.
+ * Next char in the array.
*/
#ifdef EBUG_LEXER
#define next \
- (self->stash = fgetc(self->stream)\
+ (self->stash = self->source[self->offset++]\
, fprintf(stderr, "'%c'\n", self->stash)\
, self->stash)
#else
-#define next (self->stash = fgetc(self->stream))
+#define next (self->stash = self->source[self->offset++])
#endif
/*
* Undo the previous char.
*/
-#define undo ungetc(self->stash, self->stream)
+#define undo (self->source[--self->offset] = self->stash)
/*
* Assign token `t`.
@@ -49,18 +49,19 @@
#define error(msg) (self->error = msg, token(ILLEGAL))
/*
- * Initialize lexer with the given `stream` and `filename`.
+ * Initialize lexer with the given `source` and `filename`.
*/
void
-luna_lexer_init(luna_lexer_t *self, FILE *stream, const char *filename) {
+luna_lexer_init(luna_lexer_t *self, char *source, const char *filename) {
self->error = NULL;
- self->stream = stream;
+ self->source = source;
self->filename = filename;
self->indent_stack[0] = 0;
self->indents = 0;
self->outdents = 0;
self->lineno = 1;
+ self->offset = 0;
}
/*
@@ -334,7 +335,7 @@ luna_scan(luna_lexer_t *self) {
return token(OP_GT);
case '/':
if ('/' == next) {
- while ((c = next) != '\n' && EOF != c) ; undo;
+ while ((c = next) != '\n' && c) ; undo;
goto scan;
}
return token(OP_DIV);
@@ -343,7 +344,7 @@ luna_scan(luna_lexer_t *self) {
case '"':
case '\'':
return scan_string(self, c);
- case EOF:
+ case 0:
if (self->indents) {
--self->indents;
return token(OUTDENT);
6 src/lexer.h
View
@@ -9,6 +9,7 @@
#define __LUNA_LEXER__
#include <stdio.h>
+#include <sys/stat.h>
#include "token.h"
#ifndef LUNA_BUF_SIZE
@@ -30,7 +31,8 @@ typedef struct {
int indent_stack[LUNA_MAX_INDENTS];
int indents;
int outdents;
- FILE *stream;
+ off_t offset;
+ char *source;
const char *filename;
luna_token_t tok;
char buf[LUNA_BUF_SIZE];
@@ -42,6 +44,6 @@ int
luna_scan(luna_lexer_t *self);
void
-luna_lexer_init(luna_lexer_t *self, FILE *stream, const char *filename);
+luna_lexer_init(luna_lexer_t *self, char *source, const char *filename);
#endif /* __LUNA_LEXER__ */
67 src/luna.c
View
@@ -9,21 +9,19 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#include <sys/stat.h>
#include "linenoise.h"
#include "luna.h"
#include "lexer.h"
#include "parser.h"
#include "errors.h"
+#include "utils.h"
#include "prettyprint.h"
// --ast
static int ast = 0;
-// -
-
-static int stdio = 0;
-
/*
* Output usage information.
*/
@@ -38,7 +36,6 @@ usage() {
"\n -a, --ast output ast to stdout"
"\n -h, --help output help information"
"\n -V, --version output luna version"
- "\n - read from stdin"
"\n"
"\n Examples:"
"\n"
@@ -89,18 +86,14 @@ parse_args(int *argc, const char **argv) {
for (int i = 0, len = *argc; i < len; ++i) {
arg = args[i];
- if (0 == strcmp(arg, "-h") || 0 == strcmp(arg, "--help"))
+ if (!strcmp("-h", arg) || !strcmp("--help", arg))
usage();
- else if (0 == strcmp(arg, "-V") || 0 == strcmp(arg, "--version"))
+ else if (!strcmp("-V", arg) || !strcmp("--version", arg))
version();
- else if (0 == strcmp(arg, "-a") || 0 == strcmp(arg, "--ast")) {
+ else if (!strcmp("-a", arg) || !strcmp("--ast", arg)) {
ast = 1;
--*argc;
++argv;
- } else if (0 == strcmp(arg, "-")) {
- stdio = 1;
- --*argc;
- ++argv;
} else if ('-' == arg[0]) {
fprintf(stderr, "unknown flag %s\n", arg);
exit(1);
@@ -116,51 +109,45 @@ parse_args(int *argc, const char **argv) {
int
main(int argc, const char **argv){
- int appended_ext = 0;
+ int tried_ext = 0;
const char *path, *orig;
- FILE *stream;
+ char *source;
// parse arguments
argv = parse_args(&argc, argv);
// REPL
- if (!stdio && 1 == argc) repl();
-
- // stdin
- if (stdio) {
- path = "stdin";
- stream = stdin;
- } else {
- orig = path = argv[1];
- read:
- stream = fopen(path, "r");
- if (!stream) {
- // try with .luna extension
- if (!appended_ext) {
- appended_ext = 1;
- char buf[256];
- snprintf(buf, 256, "%s.luna", path);
- path = buf;
- goto read;
- }
- fprintf(stderr, "error reading %s:\n\n %s\n\n", orig, strerror(errno));
- exit(1);
- }
- }
+ if (1 == argc) repl();
+
+ // read
+ orig = path = argv[1];
+ read:
+ if (!(source = file_read(path))) {
+ // try with .luna extension
+ if (!tried_ext) {
+ tried_ext = 1;
+ char buf[256];
+ snprintf(buf, 256, "%s.luna", path);
+ path = buf;
+ goto read;
+ }
+ fprintf(stderr, "error reading %s:\n\n %s\n\n", orig, strerror(errno));
+ exit(1);
+ }
// parse the input
luna_lexer_t lex;
- luna_lexer_init(&lex, stream, path);
+ luna_lexer_init(&lex, source, path);
luna_parser_t parser;
luna_parser_init(&parser, &lex);
luna_block_node_t *root;
-
+
// oh noes!
if (!(root = luna_parse(&parser))) {
luna_report_error(&parser);
exit(1);
}
-
+
// --ast
if (ast) {
luna_prettyprint((luna_node_t *) root);
44 src/utils.c
View
@@ -0,0 +1,44 @@
+
+//
+// utils.h
+//
+// Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
+//
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "utils.h"
+
+/*
+ * Return the filesize of `filename` or -1.
+ */
+
+off_t
+file_size(const char *filename) {
+ struct stat s;
+ if (stat(filename, &s) < 0) return -1;
+ return s.st_size;
+}
+
+/*
+ * Read the contents of `filename` or return NULL.
+ */
+
+char *
+file_read(const char *filename) {
+ off_t len = file_size(filename);
+ if (len < 0) return NULL;
+
+ char *buf = malloc(len + 1);
+ if (!buf) return NULL;
+
+ int fd = open(filename, O_RDONLY);
+ if (fd < 0) return NULL;
+
+ ssize_t size = read(fd, buf, len);
+ if (size != len) return NULL;
+
+ return buf;
+}
19 src/utils.h
View
@@ -0,0 +1,19 @@
+
+//
+// utils.h
+//
+// Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
+//
+
+#ifndef __LUNA_UTIL__
+#define __LUNA_UTIL__
+
+#include <sys/stat.h>
+
+off_t
+file_size(const char *filename);
+
+char *
+file_read(const char *filename);
+
+#endif
6 test/test.c
View
@@ -342,14 +342,14 @@ test_object_mixins() {
*/
#define suite(title) \
- printf("\n \e[96m%s\e[0m\n", title)
+ printf("\n \e[36m%s\e[0m\n", title)
/*
* Report sizeof.
*/
#define size(type) \
- printf("\n \e[90m%s: %d bytes\e[0m\n", #type, sizeof(type));
+ printf("\n \e[90m%s: %ld bytes\e[0m\n", #type, sizeof(type));
/*
* Run all test suites.
@@ -385,7 +385,7 @@ main(int argc, const char **argv){
test(string);
printf("\n");
- printf(" \e[90mcompleted in \e[33m%.5fs\e[0m\n", (float) (clock() - start) / CLOCKS_PER_SEC);
+ printf(" \e[90mcompleted in \e[32m%.5fs\e[0m\n", (float) (clock() - start) / CLOCKS_PER_SEC);
printf("\n");
return 0;
}
Please sign in to comment.
Something went wrong with that request. Please try again.