Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

parsing use statement

  • Loading branch information...
glhrmfrts committed Mar 11, 2016
1 parent 25641f3 commit 0377a08d7554c581d99f251cde384a7a27cec606
Showing with 139 additions and 4 deletions.
  1. +3 −0 examples/use.luna
  2. +15 −0 src/ast.c
  3. +15 −1 src/ast.h
  4. 0 src/ast.o-bdbde961
  5. +31 −1 src/codegen.c
  6. +2 −0 src/lexer.c
  7. +38 −0 src/parser.c
  8. +15 −1 src/prettyprint.c
  9. +2 −0 src/token.h
  10. +1 −0 src/visitor.c
  11. +2 −1 src/visitor.h
  12. +3 −0 test/parser/use.luna
  13. +6 −0 test/parser/use.out
  14. +6 −0 test/test.c
@@ -0,0 +1,3 @@
use "foo/bar/module" as mod

print(mod.foo)
@@ -367,3 +367,18 @@ luna_return_node_new(luna_node_t *expr, int lineno) {
self->expr = expr;
return self;
}

/*
* Alloc and initialize a new use node.
*/

luna_use_node_t *
luna_use_node_new(int lineno) {
luna_use_node_t *self = malloc(sizeof(luna_use_node_t));
if (unlikely(!self)) return NULL;
self->base.type = LUNA_NODE_USE;
self->base.lineno = lineno;
self->module = NULL;
self->alias = NULL;
return self;
}
@@ -43,7 +43,8 @@
n(FUNCTION) \
n(TYPE) \
n(SLOT) \
n(SUBSCRIPT)
n(SUBSCRIPT) \
n(USE)

/*
* Nodes enum.
@@ -273,6 +274,16 @@ typedef struct {
luna_node_t *expr;
} luna_return_node_t;

/*
* Luna use node.
*/

typedef struct {
luna_node_t base;
char *module;
char *alias;
} luna_use_node_t;

// protos

luna_object_t *
@@ -344,4 +355,7 @@ luna_args_node_new(int lineno);
luna_type_node_t *
luna_type_node_new(const char *name, int lineno);

luna_use_node_t *
luna_use_node_new(int lineno);

#endif /* LUNA_AST_H */
No changes.
@@ -198,6 +198,15 @@ visit_hash(luna_visitor_t *self, luna_hash_node_t *node) {
// printf(")");
}

/*
* Visit subscript `node`.
*/

static void
visit_subscript(luna_visitor_t *self, luna_subscript_node_t *node) {

}

/*
* Visit slot `node`.
*/
@@ -337,6 +346,24 @@ visit_if(luna_visitor_t *self, luna_if_node_t *node) {
// }
}

/*
* Visit `type` node.
*/

static void
visit_type(luna_visitor_t *self, luna_type_node_t *node) {

}

/*
* Visit use `node`.
*/

static void
visit_use(luna_visitor_t *self, luna_use_node_t *node) {

}

/*
* Generate code for the given `node`.
*/
@@ -367,7 +394,10 @@ luna_gen(luna_node_t *node) {
.visit_return = visit_return,
.visit_function = visit_function,
.visit_unary_op = visit_unary_op,
.visit_binary_op = visit_binary_op
.visit_binary_op = visit_binary_op,
.visit_subscript = visit_subscript,
.visit_type = visit_type,
.visit_use = visit_use
};

luna_visit(&visitor, node);
@@ -101,8 +101,10 @@ scan_ident(luna_lexer_t *self, int c) {
switch (len-1) {
case 2:
if (0 == strcmp("if", buf)) return token(IF);
if (0 == strcmp("as", buf)) return token(AS);
break;
case 3:
if (0 == strcmp("use", buf)) return token(USE);
if (0 == strcmp("for", buf)) return token(FOR);
if (0 == strcmp("def", buf)) return token(DEF);
if (0 == strcmp("end", buf)) return token(END);
@@ -1133,6 +1133,43 @@ return_stmt(luna_parser_t *self) {
return (luna_node_t *) luna_return_node_new(node, line);
}

/*
* 'use' string ('as' id)?
*/

static luna_node_t *
use_stmt(luna_parser_t *self) {
//puts("asçkdhakjshd");

int line = lineno;
debug("use");
context("use statement");

// 'use'
if (!accept(USE)) return NULL;
luna_use_node_t *node = luna_use_node_new(line);

// string
if (!is(STRING)) {
return error("missing module name");
}
node->module = self->tok->value.as_string;
next;

// 'as'
if (accept(AS)) {

// id
if (!is(ID)) {
return error("missing alias name");
}
node->alias = self->tok->value.as_string;
next;
}

return (luna_node_t *) node;
}

/*
* if_stmt
* | while_stmt
@@ -1151,6 +1188,7 @@ stmt(luna_parser_t *self) {
if (is(RETURN)) return return_stmt(self);
if (is(DEF)) return function_stmt(self);
if (is(TYPE)) return type_stmt(self);
if (is(USE)) return use_stmt(self);
return expr(self);
}

@@ -456,6 +456,19 @@ visit_if(luna_visitor_t *self, luna_if_node_t *node) {
}
}

/*
* Visit use `node`.
*/

static void
visit_use(luna_visitor_t *self, luna_use_node_t *node) {
print_func("(use \'%s\'", node->module);
if (node->alias) {
print_func(" as %s", node->alias);
}
print_func(")");
}

/*
* Pretty-print the given `node` to stdout.
*/
@@ -481,7 +494,8 @@ luna_prettyprint(luna_node_t *node) {
.visit_unary_op = visit_unary_op,
.visit_binary_op = visit_binary_op,
.visit_subscript = visit_subscript,
.visit_type = visit_type
.visit_type = visit_type,
.visit_use = visit_use
};

luna_visit(&visitor, node);
@@ -23,6 +23,8 @@
t(STRING, "string") \
t(DEF, "def") \
t(TYPE, "type") \
t(USE, "use") \
t(AS, "as") \
t(WHILE, "while") \
t(UNTIL, "until") \
t(IF, "if") \
@@ -42,5 +42,6 @@ luna_visit(luna_visitor_t *self, luna_node_t *node) {
case LUNA_NODE_ARRAY: VISIT(array);
case LUNA_NODE_HASH: VISIT(hash);
case LUNA_NODE_RETURN: VISIT(return);
case LUNA_NODE_USE: VISIT(use);
}
}
@@ -42,7 +42,8 @@ typedef struct luna_visitor {
// TODO: discover why the program crashes if i put this somewhere else
void (* visit_subscript)(struct luna_visitor *self, luna_subscript_node_t *node);
void (* visit_type)(struct luna_visitor *self, luna_type_node_t *node);
void ( *visit_let)(struct luna_visitor *self, luna_let_node_t *node);
void (* visit_let)(struct luna_visitor *self, luna_let_node_t *node);
void (* visit_use)(struct luna_visitor *self, luna_use_node_t *node);
} luna_visitor_t;

// protos
@@ -0,0 +1,3 @@
use "foo"
use "foo/bar"
use "foo" as bar
@@ -0,0 +1,6 @@
(use 'foo')

(use 'foo/bar')

(use 'foo' as bar)

@@ -370,6 +370,11 @@ test_return() {
_test_parser("test/parser/return.luna", "test/parser/return.out");
}

static void
test_use() {
_test_parser("test/parser/use.luna", "test/parser/use.out");
}

/*
* Test the given `fn`.
*/
@@ -427,6 +432,7 @@ main(int argc, const char **argv){
test(subscript);
test(declaration);
test(return);
test(use);

printf("\n");
printf(" \e[90mcompleted in \e[32m%.5fs\e[0m\n", (float) (clock() - start) / CLOCKS_PER_SEC);

0 comments on commit 0377a08

Please sign in to comment.
You can’t perform that action at this time.