summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/compile.h37
-rw-r--r--src/parse.y77
-rw-r--r--test/driver.c12
-rw-r--r--tools/mrbc/mrbc.c2
-rw-r--r--tools/mruby/mruby.c15
5 files changed, 95 insertions, 48 deletions
diff --git a/include/mruby/compile.h b/include/mruby/compile.h
index 2ea141da8..401f52854 100644
--- a/include/mruby/compile.h
+++ b/include/mruby/compile.h
@@ -14,13 +14,26 @@ extern "C" {
#include "mruby.h"
#include <stdio.h>
#include <setjmp.h>
+#include <stdio.h>
+
+/* load context */
+typedef struct mrbc_context {
+ mrb_sym *syms;
+ int slen;
+ char *filename;
+ int lineno;
+} mrbc_context;
+
+mrbc_context* mrbc_context_new(mrb_state *mrb);
+void mrbc_context_free(mrb_state *mrb, mrbc_context *cxt);
+const char *mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s);
+/* AST node structure */
typedef struct mrb_ast_node {
struct mrb_ast_node *car, *cdr;
} mrb_ast_node;
-#include <stdio.h>
-
+/* lexer states */
enum mrb_lex_state_enum {
EXPR_BEG, /* ignore newline, +/- is a sign. */
EXPR_END, /* newline significant, +/- is an operator. */
@@ -36,21 +49,23 @@ enum mrb_lex_state_enum {
EXPR_MAX_STATE
};
+/* saved error message */
struct mrb_parser_message {
int lineno;
int column;
char* message;
};
+/* parser structure */
struct mrb_parser_state {
mrb_state *mrb;
struct mrb_pool *pool;
mrb_ast_node *cells;
const char *s, *send;
FILE *f;
+ char *filename;
int lineno;
int column;
- const char *filename;
enum mrb_lex_state_enum lstate;
int sterm;
@@ -59,6 +74,8 @@ struct mrb_parser_state {
unsigned int cmdarg_stack;
int paren_nest;
int lpar_beg;
+ int in_def, in_single, cmd_start;
+ mrb_ast_node *locals;
mrb_ast_node *pb;
char buf[1024];
@@ -66,9 +83,6 @@ struct mrb_parser_state {
mrb_ast_node *heredoc;
- int in_def, in_single, cmd_start;
- mrb_ast_node *locals;
-
void *ylval;
int nerr;
@@ -82,22 +96,23 @@ struct mrb_parser_state {
jmp_buf jmp;
};
-/* parser structure */
struct mrb_parser_state* mrb_parser_new(mrb_state*);
const char *mrb_parser_filename(struct mrb_parser_state*, const char*);
-int mrb_parser_lineno(struct mrb_parser_state*, int);
void mrb_parser_parse(struct mrb_parser_state*);
/* utility functions */
-struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*);
-struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*);
-struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,int);
+struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*,mrbc_context*);
+struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*,mrbc_context*);
+struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,int,mrbc_context*);
int mrb_generate_code(mrb_state*, mrb_ast_node*);
/* program load functions */
mrb_value mrb_load_file(mrb_state*,FILE*);
mrb_value mrb_load_string(mrb_state *mrb, const char *path);
mrb_value mrb_load_nstring(mrb_state *mrb, const char *path, int len);
+mrb_value mrb_load_file_cxt(mrb_state*,FILE*, mrbc_context *cxt);
+mrb_value mrb_load_string_cxt(mrb_state *mrb, const char *path, mrbc_context *cxt);
+mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const char *path, int len, mrbc_context *cxt);
#if defined(__cplusplus)
} /* extern "C" { */
diff --git a/src/parse.y b/src/parse.y
index 7f40534b9..78d7d7a7e 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -4730,7 +4730,6 @@ mrb_parser_new(mrb_state *mrb)
p->in_def = p->in_single = FALSE;
p->capture_errors = 0;
-
p->lineno = 1;
p->column = 0;
#if defined(PARSER_TEST) || defined(PARSER_DEBUG)
@@ -4740,33 +4739,56 @@ mrb_parser_new(mrb_state *mrb)
return p;
}
+mrbc_context*
+mrbc_context_new(mrb_state *mrb)
+{
+ mrbc_context *c;
+
+ c = mrb_malloc(mrb, sizeof(mrbc_context));
+ memset(c, 0, sizeof(mrbc_context));
+ return c;
+}
+
+void
+mrbc_context_free(mrb_state *mrb, mrbc_context *cxt)
+{
+ mrb_free(mrb, cxt->syms);
+ mrb_free(mrb, cxt->filename);
+ mrb_free(mrb, cxt);
+}
+
const char*
-mrb_parser_filename(parser_state *p, const char *s)
+mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s)
{
if (s) {
- p->filename = strdup(s);
+ int len = strlen(s);
+ char *p = mrb_malloc(mrb, len);
+
+ memcpy(p, s, len);
+ if (c->filename) mrb_free(mrb, c->filename);
+ c->filename = p;
+ c->lineno = 1;
}
- return p->filename;
+ return c->filename;
}
-int
-mrb_parser_lineno(struct mrb_parser_state *p, int n)
+static void
+parser_init_cxt(parser_state *p, mrbc_context *cxt)
{
- if (n <= 0) {
- return p->lineno;
+ if (cxt) {
+ if (cxt->lineno) p->lineno = cxt->lineno;
+ if (cxt->filename) p->filename = cxt->filename;
}
- p->column = 0;
- p->lineno = n;
- return n;
}
parser_state*
-mrb_parse_file(mrb_state *mrb, FILE *f)
+mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c)
{
parser_state *p;
p = mrb_parser_new(mrb);
if (!p) return 0;
+ parser_init_cxt(p, c);
p->s = p->send = NULL;
p->f = f;
@@ -4775,12 +4797,13 @@ mrb_parse_file(mrb_state *mrb, FILE *f)
}
parser_state*
-mrb_parse_nstring(mrb_state *mrb, const char *s, int len)
+mrb_parse_nstring(mrb_state *mrb, const char *s, int len, mrbc_context *c)
{
parser_state *p;
p = mrb_parser_new(mrb);
if (!p) return 0;
+ parser_init_cxt(p, c);
p->s = s;
p->send = s + len;
@@ -4789,9 +4812,9 @@ mrb_parse_nstring(mrb_state *mrb, const char *s, int len)
}
parser_state*
-mrb_parse_string(mrb_state *mrb, const char *s)
+mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c)
{
- return mrb_parse_nstring(mrb, s, strlen(s));
+ return mrb_parse_nstring(mrb, s, strlen(s), c);
}
static mrb_value
@@ -4818,21 +4841,39 @@ load_exec(mrb_state *mrb, parser_state *p)
}
mrb_value
+mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c)
+{
+ return load_exec(mrb, mrb_parse_file(mrb, f, c));
+}
+
+mrb_value
mrb_load_file(mrb_state *mrb, FILE *f)
{
- return load_exec(mrb, mrb_parse_file(mrb, f));
+ return mrb_load_file_cxt(mrb, f, NULL);
+}
+
+mrb_value
+mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *c)
+{
+ return load_exec(mrb, mrb_parse_nstring(mrb, s, len, c));
}
mrb_value
mrb_load_nstring(mrb_state *mrb, const char *s, int len)
{
- return load_exec(mrb, mrb_parse_nstring(mrb, s, len));
+ return mrb_load_nstring_cxt(mrb, s, len, NULL);
+}
+
+mrb_value
+mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *c)
+{
+ return load_exec(mrb, mrb_parse_nstring(mrb, s, strlen(s), c));
}
mrb_value
mrb_load_string(mrb_state *mrb, const char *s)
{
- return load_exec(mrb, mrb_parse_nstring(mrb, s, strlen(s)));
+ return mrb_load_string_cxt(mrb, s, NULL);
}
void parser_dump(mrb_state *mrb, node *tree, int offset);
diff --git a/test/driver.c b/test/driver.c
index 6b42d025b..6b1697f14 100644
--- a/test/driver.c
+++ b/test/driver.c
@@ -42,16 +42,8 @@ main(void)
}
mrb_init_mrbtest(mrb);
- parser = mrb_parse_nstring(mrb, prog, strlen(prog));
-
- /* generate bytecode */
- byte_code = mrb_generate_code(mrb, parser->tree);
-
- /* evaluate the bytecode */
- return_value = mrb_run(mrb,
- /* pass a proc for evaulation */
- mrb_proc_new(mrb, mrb->irep[byte_code]),
- mrb_top_self(mrb));
+ /* evaluate the test */
+ return_value = mrb_load_string(mrb, prog);
/* did an exception occur? */
if (mrb->exc) {
mrb_p(mrb, return_value);
diff --git a/tools/mrbc/mrbc.c b/tools/mrbc/mrbc.c
index 99fea76d8..9b69244e5 100644
--- a/tools/mrbc/mrbc.c
+++ b/tools/mrbc/mrbc.c
@@ -172,7 +172,7 @@ main(int argc, char **argv)
return n;
}
- p = mrb_parse_file(mrb, args.rfp);
+ p = mrb_parse_file(mrb, args.rfp, NULL);
if (!p || !p->tree || p->nerr) {
cleanup(&args);
mrb_close(mrb);
diff --git a/tools/mruby/mruby.c b/tools/mruby/mruby.c
index 5cf3d8a37..b4b37516b 100644
--- a/tools/mruby/mruby.c
+++ b/tools/mruby/mruby.c
@@ -165,17 +165,16 @@ main(int argc, char **argv)
n = mrb_load_irep(mrb, args.rfp);
}
else {
+ mrbc_context *c = mrbc_context_new(mrb);
if (args.cmdline) {
- p = mrb_parse_string(mrb, (char*)args.cmdline);
- }
+ mrbc_filename(mrb, c, "-e");
+ p = mrb_parse_string(mrb, (char*)args.cmdline, c);
+ }
else {
- p = mrb_parser_new(mrb);
- if (p) {
- mrb_parser_filename(p, argv[1]);
- p->f = args.rfp;
- mrb_parser_parse(p);
- }
+ mrbc_filename(mrb, c, argv[1]);
+ p = mrb_parse_file(mrb, args.rfp, c);
}
+ mrbc_context_free(mrb, c);
if (!p || !p->tree || p->nerr) {
cleanup(mrb, &args);
return -1;