summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--build_config.rb3
-rw-r--r--include/mrbconf.h9
-rw-r--r--include/mruby.h3
-rw-r--r--include/mruby/array.h18
-rw-r--r--include/mruby/compile.h22
-rw-r--r--include/mruby/string.h6
-rw-r--r--mrbgems/mruby-math/src/math.c40
-rw-r--r--mrbgems/mruby-sprintf/mrbgem.rake4
-rw-r--r--mrbgems/mruby-sprintf/src/kernel.c30
-rw-r--r--mrbgems/mruby-sprintf/src/sprintf.c (renamed from src/sprintf.c)8
-rw-r--r--mrbgems/mruby-sprintf/test/sprintf.rb3
-rw-r--r--mrbgems/mruby-struct/src/struct.c6
-rw-r--r--mrblib/array.rb2
-rw-r--r--mrblib/compar.rb4
-rw-r--r--mrblib/enum.rb12
-rw-r--r--mrblib/hash.rb2
-rw-r--r--src/array.c90
-rw-r--r--src/class.c12
-rw-r--r--src/codegen.c55
-rw-r--r--src/error.c26
-rw-r--r--src/gc.c4
-rw-r--r--src/hash.c8
-rw-r--r--src/kernel.c13
-rw-r--r--src/load.c2
-rw-r--r--src/node.h1
-rw-r--r--src/numeric.c8
-rw-r--r--src/parse.y1549
-rw-r--r--src/range.c8
-rw-r--r--src/state.c8
-rw-r--r--src/string.c13
-rw-r--r--src/variable.c2
-rw-r--r--test/t/literals.rb69
-rw-r--r--tools/mirb/mirb.c7
34 files changed, 1207 insertions, 843 deletions
diff --git a/README.md b/README.md
index 93a9c0f01..32d177334 100644
--- a/README.md
+++ b/README.md
@@ -110,6 +110,7 @@ Please ask us if you want to distribute your code under another license.
## How to Contribute
-Send pull request to <http://github.com/mruby/mruby>. We consider you have granted
+See the [contribution guidelines](https://github.com/mruby/mruby/blob/master/CONTRIBUTING.md)
+then send a pull request to <http://github.com/mruby/mruby>. We consider you have granted
non-exclusive right to your contributed code under MIT license. If you want to be named
as one of mruby developers, include update to the AUTHORS file in your pull request.
diff --git a/build_config.rb b/build_config.rb
index d3feccd71..3c089d8cc 100644
--- a/build_config.rb
+++ b/build_config.rb
@@ -20,6 +20,9 @@ MRuby::Build.new do |conf|
# Use standard Struct class
conf.gem 'mrbgems/mruby-struct'
+ # Use standard Kernel#sprintf method
+ conf.gem 'mrbgems/mruby-sprintf'
+
# Generate binaries
# conf.bins = %w(mrbc mruby mirb)
diff --git a/include/mrbconf.h b/include/mrbconf.h
index c84480af7..8a46e48ba 100644
--- a/include/mrbconf.h
+++ b/include/mrbconf.h
@@ -23,7 +23,7 @@
//#define MRB_ENDIAN_BIG
/* argv max size in mrb_funcall */
-//#define MRB_FUNCALL_ARGC_MAX 16
+//#define MRB_FUNCALL_ARGC_MAX 16
/* number of object per heap page */
//#define MRB_HEAP_PAGE_SIZE 1024
@@ -34,6 +34,9 @@
/* initial size for IV khash; ignored when MRB_USE_IV_SEGLIST is set */
//#define MRB_IVHASH_INIT_SIZE 8
+/* initial size for IREP array */
+//#define MRB_IREP_ARRAY_INIT_SIZE (256u)
+
/* default size of khash table bucket */
//#define KHASH_DEFAULT_SIZE 32
@@ -44,7 +47,6 @@
//#define POOL_PAGE_SIZE 16000
/* -DDISABLE_XXXX to drop following features */
-//#define DISABLE_SPRINTF /* Kernel.sprintf method */
//#define DISABLE_STDIO /* use of stdio */
/* -DENABLE_XXXX to enable following features */
@@ -80,9 +82,6 @@
typedef short mrb_sym;
/* define ENABLE_XXXX from DISABLE_XXX */
-#ifndef DISABLE_SPRINTF
-#define ENABLE_SPRINTF
-#endif
#ifndef DISABLE_STDIO
#define ENABLE_STDIO
#endif
diff --git a/include/mruby.h b/include/mruby.h
index 61df6e9ed..fe97dd055 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -129,9 +129,6 @@ typedef struct mrb_state {
mrb_sym symidx;
struct kh_n2s *name2sym; /* symbol table */
-#ifdef INCLUDE_REGEXP
- struct RNode *local_svar;/* regexp */
-#endif
#ifdef ENABLE_DEBUG
void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs);
diff --git a/include/mruby/array.h b/include/mruby/array.h
index 9f9483545..5d78ccddd 100644
--- a/include/mruby/array.h
+++ b/include/mruby/array.h
@@ -14,14 +14,14 @@ extern "C" {
typedef struct mrb_shared_array {
int refcnt;
mrb_value *ptr;
- int len;
+ mrb_int len;
} mrb_shared_array;
struct RArray {
MRB_OBJECT_HEADER;
- int len;
+ mrb_int len;
union {
- int capa;
+ mrb_int capa;
mrb_shared_array *shared;
} aux;
mrb_value *ptr;
@@ -36,24 +36,24 @@ struct RArray {
#define MRB_ARY_SHARED 256
void mrb_ary_decref(mrb_state*, mrb_shared_array*);
-mrb_value mrb_ary_new_capa(mrb_state*, int);
+mrb_value mrb_ary_new_capa(mrb_state*, mrb_int);
mrb_value mrb_ary_new(mrb_state *mrb);
-mrb_value mrb_ary_new_elts(mrb_state *mrb, int n, const mrb_value *elts);
+mrb_value mrb_ary_new_elts(mrb_state *mrb, mrb_int n, const mrb_value *elts);
void mrb_ary_concat(mrb_state*, mrb_value, mrb_value);
mrb_value mrb_ary_splat(mrb_state*, mrb_value);
void mrb_ary_push(mrb_state*, mrb_value, mrb_value);
mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary);
-mrb_value mrb_ary_new_from_values(mrb_state *mrb, int size, mrb_value *vals);
+mrb_value mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, mrb_value *vals);
mrb_value mrb_ary_aget(mrb_state *mrb, mrb_value self);
mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n);
void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val);
-int mrb_ary_len(mrb_state *mrb, mrb_value ary);
+mrb_int mrb_ary_len(mrb_state *mrb, mrb_value ary);
void mrb_ary_replace(mrb_state *mrb, mrb_value a, mrb_value b);
mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self);
mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item);
-mrb_value mrb_ary_new4(mrb_state *mrb, int n, const mrb_value *elts);
+mrb_value mrb_ary_new4(mrb_state *mrb, mrb_int n, const mrb_value *elts);
mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr);
-mrb_value mrb_ary_entry(mrb_value ary, int offset);
+mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset);
mrb_value mrb_ary_shift(mrb_state *mrb, mrb_value self);
mrb_value mrb_ary_clear(mrb_state *mrb, mrb_value self);
diff --git a/include/mruby/compile.h b/include/mruby/compile.h
index d0de0153b..2cbc28321 100644
--- a/include/mruby/compile.h
+++ b/include/mruby/compile.h
@@ -59,6 +59,21 @@ struct mrb_parser_message {
char* message;
};
+/* heredoc parse type */
+enum heredoc_type {
+ heredoc_type_norm, /* <<EOH */
+ heredoc_type_quote, /* <<'EOH' */
+};
+/* heredoc structure */
+struct mrb_parser_heredoc_info {
+ enum heredoc_type type;
+ int allow_indent:1;
+ int line_head:1;
+ const char *term;
+ int term_len;
+ mrb_ast_node *doc;
+};
+
/* parser structure */
struct mrb_parser_state {
mrb_state *mrb;
@@ -71,7 +86,7 @@ struct mrb_parser_state {
int column;
enum mrb_lex_state_enum lstate;
- int sterm;
+ int sterm; /* string terminator : ' ' means heredoc */
int regexp;
unsigned int cond_stack;
@@ -85,7 +100,10 @@ struct mrb_parser_state {
char buf[1024];
int bidx;
- mrb_ast_node *heredoc;
+ mrb_ast_node *heredocs; /* list of mrb_parser_heredoc_info* */
+ mrb_ast_node *parsing_heredoc;
+ int heredoc_starts_nextline:1;
+ int heredoc_end_now:1; /* for mirb */
void *ylval;
diff --git a/include/mruby/string.h b/include/mruby/string.h
index 353d8cefc..3f661a742 100644
--- a/include/mruby/string.h
+++ b/include/mruby/string.h
@@ -24,14 +24,14 @@ extern const char mrb_digitmap[];
typedef struct mrb_shared_string {
int refcnt;
char *ptr;
- int len;
+ mrb_int len;
} mrb_shared_string;
struct RString {
MRB_OBJECT_HEADER;
- int len;
+ mrb_int len;
union {
- int capa;
+ mrb_int capa;
mrb_shared_string *shared;
} aux;
char *ptr;
diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c
index 9955d9862..76058250f 100644
--- a/mrbgems/mruby-math/src/math.c
+++ b/mrbgems/mruby-math/src/math.c
@@ -26,13 +26,13 @@
double
erfc(double x);
-/*
+/*
** Implementations of error functions
** credits to http://www.digitalmars.com/archives/cplusplus/3634.html
*/
/* Implementation of Error function */
-double
+double
erf(double x)
{
static const double two_sqrtpi = 1.128379167095512574;
@@ -55,24 +55,24 @@ erf(double x)
}
/* Implementation of complementary Error function */
-double
+double
erfc(double x)
{
- static const double one_sqrtpi= 0.564189583547756287;
- double a = 1;
- double b = x;
- double c = x;
- double d = x*x+0.5;
+ static const double one_sqrtpi= 0.564189583547756287;
+ double a = 1;
+ double b = x;
+ double c = x;
+ double d = x*x+0.5;
double q1;
double q2 = b/d;
double n = 1.0;
double t;
if (fabs(x) < 2.2) {
- return 1.0 - erf(x);
- }
- if (x < 0.0) { /*signbit(x)*/
- return 2.0 - erfc(-x);
- }
+ return 1.0 - erf(x);
+ }
+ if (x < 0.0) { /*signbit(x)*/
+ return 2.0 - erfc(-x);
+ }
do {
t = a*n+b*x;
a = b;
@@ -306,7 +306,7 @@ math_asinh(mrb_state *mrb, mrb_value obj)
mrb_float x;
mrb_get_args(mrb, "f", &x);
-
+
x = asinh(x);
return mrb_float_value(x);
@@ -477,10 +477,10 @@ static mrb_value
math_sqrt(mrb_state *mrb, mrb_value obj)
{
mrb_float x;
-
+
mrb_get_args(mrb, "f", &x);
x = sqrt(x);
-
+
return mrb_float_value(x);
}
@@ -544,7 +544,7 @@ math_frexp(mrb_state *mrb, mrb_value obj)
{
mrb_float x;
int exp;
-
+
mrb_get_args(mrb, "f", &x);
x = frexp(x, &exp);
@@ -633,13 +633,13 @@ mrb_mruby_math_gem_init(mrb_state* mrb)
{
struct RClass *mrb_math;
mrb_math = mrb_define_module(mrb, "Math");
-
+
#ifdef M_PI
mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(M_PI));
#else
mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(atan(1.0)*4.0));
#endif
-
+
#ifdef M_E
mrb_define_const(mrb, mrb_math, "E", mrb_float_value(M_E));
#else
@@ -660,7 +660,7 @@ mrb_mruby_math_gem_init(mrb_state* mrb)
mrb_define_module_function(mrb, mrb_math, "acos", math_acos, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "atan", math_atan, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "atan2", math_atan2, ARGS_REQ(2));
-
+
mrb_define_module_function(mrb, mrb_math, "sinh", math_sinh, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "cosh", math_cosh, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "tanh", math_tanh, ARGS_REQ(1));
diff --git a/mrbgems/mruby-sprintf/mrbgem.rake b/mrbgems/mruby-sprintf/mrbgem.rake
new file mode 100644
index 000000000..8772a5174
--- /dev/null
+++ b/mrbgems/mruby-sprintf/mrbgem.rake
@@ -0,0 +1,4 @@
+MRuby::Gem::Specification.new('mruby-sprintf') do |spec|
+ spec.license = 'MIT'
+ spec.authors = 'mruby developers'
+end
diff --git a/mrbgems/mruby-sprintf/src/kernel.c b/mrbgems/mruby-sprintf/src/kernel.c
new file mode 100644
index 000000000..8f54a3d85
--- /dev/null
+++ b/mrbgems/mruby-sprintf/src/kernel.c
@@ -0,0 +1,30 @@
+/*
+** kernel.c - Kernel module suppliment
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include "mruby.h"
+
+mrb_value mrb_f_sprintf(mrb_state *mrb, mrb_value obj); /* in sprintf.c */
+
+void
+mrb_mruby_sprintf_gem_init(mrb_state* mrb)
+{
+ struct RClass *krn;
+
+ if (mrb->kernel_module == NULL) {
+ mrb->kernel_module = mrb_define_module(mrb, "Kernel"); /* Might be PARANOID. */
+ }
+ krn = mrb->kernel_module;
+
+ mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, ARGS_ANY());
+ mrb_define_method(mrb, krn, "format", mrb_f_sprintf, ARGS_ANY());
+}
+
+void
+mrb_mruby_sprintf_gem_final(mrb_state* mrb)
+{
+ /* nothing to do. */
+}
+
diff --git a/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c
index 905182147..12ed05d13 100644
--- a/src/sprintf.c
+++ b/mrbgems/mruby-sprintf/src/sprintf.c
@@ -6,8 +6,6 @@
#include "mruby.h"
-#ifdef ENABLE_SPRINTF
-
#include <stdio.h>
#include <string.h>
#include "mruby/string.h"
@@ -623,7 +621,7 @@ retry:
p++;
goto retry;
}
-
+
case '*':
CHECK_FOR_WIDTH(flags);
flags |= FWIDTH;
@@ -658,7 +656,7 @@ retry:
case '\n':
case '\0':
p--;
-
+
case '%':
if (flags != FNONE) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format character - %");
@@ -1091,5 +1089,3 @@ fmt_setup(char *buf, size_t size, int c, int flags, int width, int prec)
*buf++ = c;
*buf = '\0';
}
-
-#endif /* ENABLE_SPRINTF */
diff --git a/mrbgems/mruby-sprintf/test/sprintf.rb b/mrbgems/mruby-sprintf/test/sprintf.rb
new file mode 100644
index 000000000..52e94fb83
--- /dev/null
+++ b/mrbgems/mruby-sprintf/test/sprintf.rb
@@ -0,0 +1,3 @@
+##
+# Kernel#sprintf Kernel#format Test
+
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c
index a49d8244b..33997b294 100644
--- a/mrbgems/mruby-struct/src/struct.c
+++ b/mrbgems/mruby-struct/src/struct.c
@@ -352,8 +352,8 @@ mrb_struct_s_def(mrb_state *mrb, mrb_value klass)
mrb_get_args(mrb, "*&", &argv, &argc, &b);
if (argc == 0) { /* special case to avoid crash */
rest = mrb_ary_new(mrb);
- }
- else {
+ }
+ else {
if (argc > 0) name = argv[0];
if (argc > 1) rest = argv[1];
if (mrb_array_p(rest)) {
@@ -378,7 +378,7 @@ mrb_struct_s_def(mrb_state *mrb, mrb_value klass)
id = mrb_to_id(mrb, RARRAY_PTR(rest)[i]);
RARRAY_PTR(rest)[i] = mrb_symbol_value(id);
}
- }
+ }
st = make_struct(mrb, name, rest, struct_class(mrb));
if (!mrb_nil_p(b)) {
mrb_funcall(mrb, b, "call", 1, &st);
diff --git a/mrblib/array.rb b/mrblib/array.rb
index abbb38cb6..82df90950 100644
--- a/mrblib/array.rb
+++ b/mrblib/array.rb
@@ -52,7 +52,7 @@ class Array
##
# Alias for collect!
- #
+ #
# ISO 15.2.12.5.20
alias map! collect!
diff --git a/mrblib/compar.rb b/mrblib/compar.rb
index 9f2ab887d..40fb2e7f0 100644
--- a/mrblib/compar.rb
+++ b/mrblib/compar.rb
@@ -25,7 +25,7 @@ module Comparable
# Return true if +self+ is less
# than or equal to +other+.
# Otherwise return false.
- #
+ #
# ISO 15.3.3.2.2
def <= other
cmp = self <=> other
@@ -88,7 +88,7 @@ module Comparable
end
##
- # Return true if +self+ is greater
+ # Return true if +self+ is greater
# than or equal to +min+ and
# less than or equal to +max+.
# Otherwise return false.
diff --git a/mrblib/enum.rb b/mrblib/enum.rb
index 2774bc856..0593e1f04 100644
--- a/mrblib/enum.rb
+++ b/mrblib/enum.rb
@@ -73,7 +73,7 @@ module Enumerable
##
# Call the given block for each element
# which is yield by +each+. Append all
- # values of each block together and
+ # values of each block together and
# return this value.
#
# ISO 15.3.2.2.3
@@ -89,7 +89,7 @@ module Enumerable
# Call the given block for each element
# which is yield by +each+. Return
# +ifnone+ if no block value was true.
- # Otherwise return the first block value
+ # Otherwise return the first block value
# which had was true.
#
# ISO 15.3.2.2.4
@@ -158,8 +158,8 @@ module Enumerable
# Call the given block for each element
# which is yield by +each+ and which return
# value was true when invoking === with
- # +pattern+. Return an array with all
- # elements or the respective block values.
+ # +pattern+. Return an array with all
+ # elements or the respective block values.
#
# ISO 15.3.2.2.9
def grep(pattern, &block)
@@ -291,9 +291,9 @@ module Enumerable
##
# Call the given block for each element
- # which is yield by +each+. Return an
+ # which is yield by +each+. Return an
# array which contains two arrays. The
- # first array contains all elements
+ # first array contains all elements
# whose block value was true. The second
# array contains all elements whose
# block value was false.
diff --git a/mrblib/hash.rb b/mrblib/hash.rb
index 7b7b3f8ac..c304d4845 100644
--- a/mrblib/hash.rb
+++ b/mrblib/hash.rb
@@ -64,7 +64,7 @@ class Hash
# it will be called for each element with
# a duplicate key. The value of the block
# will be the final value of this element.
- #
+ #
# ISO 15.2.13.4.22
def merge(other, &block)
h = {}
diff --git a/src/array.c b/src/array.c
index c767283aa..b55a47f66 100644
--- a/src/array.c
+++ b/src/array.c
@@ -10,14 +10,18 @@
#include "mruby/string.h"
#include "mruby/class.h"
+/* SIZE_MAX is not supported by VC++. */
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t)-1)
+#endif
+
#define ARY_DEFAULT_LEN 4
#define ARY_SHRINK_RATIO 5 /* must be larger than 2 */
-#ifdef INT_MAX
-# define ARY_MAX_SIZE (INT_MAX / sizeof(mrb_value))
-#endif
+#define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value))
+#define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX)
static inline mrb_value
-ary_elt(mrb_value ary, int offset)
+ary_elt(mrb_value ary, mrb_int offset)
{
if (RARRAY_LEN(ary) == 0) return mrb_nil_value();
if (offset < 0 || RARRAY_LEN(ary) <= offset) {
@@ -27,16 +31,14 @@ ary_elt(mrb_value ary, int offset)
}
static struct RArray*
-ary_new_capa(mrb_state *mrb, int capa)
+ary_new_capa(mrb_state *mrb, mrb_int capa)
{
struct RArray *a;
- int blen;
+ mrb_int blen;
-#ifdef INT_MAX
if (capa > ARY_MAX_SIZE) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "ary size too big");
}
-#endif
blen = capa * sizeof(mrb_value) ;
if (blen < capa) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "ary size too big");
@@ -51,7 +53,7 @@ ary_new_capa(mrb_state *mrb, int capa)
}
mrb_value
-mrb_ary_new_capa(mrb_state *mrb, int capa)
+mrb_ary_new_capa(mrb_state *mrb, mrb_int capa)
{
struct RArray *a = ary_new_capa(mrb, capa);
return mrb_obj_value(a);
@@ -89,7 +91,7 @@ array_copy(mrb_value *dst, const mrb_value *src, size_t size)
mrb_value
-mrb_ary_new_from_values(mrb_state *mrb, int size, mrb_value *vals)
+mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, mrb_value *vals)
{
mrb_value ary;
struct RArray *a;
@@ -112,7 +114,7 @@ mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr)
}
static void
-ary_fill_with_nil(mrb_value *ptr, int size)
+ary_fill_with_nil(mrb_value *ptr, mrb_int size)
{
mrb_value nil = mrb_nil_value();
@@ -134,13 +136,13 @@ ary_modify(mrb_state *mrb, struct RArray *a)
}
else {
mrb_value *ptr, *p;
- int len;
+ mrb_int len;
p = a->ptr;
len = a->len * sizeof(mrb_value);
ptr = (mrb_value *)mrb_malloc(mrb, len);
if (p) {
- array_copy(ptr, p, a->len);
+ array_copy(ptr, p, a->len);
}
a->ptr = ptr;
a->aux.capa = a->len;
@@ -170,15 +172,13 @@ ary_make_shared(mrb_state *mrb, struct RArray *a)
}
static void
-ary_expand_capa(mrb_state *mrb, struct RArray *a, int len)
+ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len)
{
- int capa = a->aux.capa;
+ mrb_int capa = a->aux.capa;
-#ifdef INT_MAX
if (len > ARY_MAX_SIZE) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
}
-#endif
while(capa < len) {
if (capa == 0) {
@@ -189,9 +189,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, int len)
}
}
-#ifdef INT_MAX
if (capa > ARY_MAX_SIZE) capa = ARY_MAX_SIZE; /* len <= capa <= ARY_MAX_SIZE */
-#endif
if (capa > a->aux.capa) {
a->aux.capa = capa;
@@ -202,7 +200,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, int len)
static void
ary_shrink_capa(mrb_state *mrb, struct RArray *a)
{
- int capa = a->aux.capa;
+ mrb_int capa = a->aux.capa;
if (capa < ARY_DEFAULT_LEN * 2) return;
if (capa <= a->len * ARY_SHRINK_RATIO) return;
@@ -228,13 +226,13 @@ mrb_ary_s_create(mrb_state *mrb, mrb_value self)
int len;
mrb_get_args(mrb, "*", &vals, &len);
- return mrb_ary_new_from_values(mrb, (int)len, vals);
+ return mrb_ary_new_from_values(mrb, len, vals);
}
static void
-ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, int blen)
+ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, mrb_int blen)
{
- int len = a->len + blen;
+ mrb_int len = a->len + blen;
ary_modify(mrb, a);
if (a->aux.capa < len) ary_expand_capa(mrb, a, len);
@@ -255,7 +253,7 @@ mrb_value
mrb_ary_concat_m(mrb_state *mrb, mrb_value self)
{
mrb_value *ptr;
- int blen;
+ mrb_int blen;
mrb_get_args(mrb, "a", &ptr, &blen);
ary_concat(mrb, mrb_ary_ptr(self), ptr, blen);
@@ -269,7 +267,7 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self)
struct RArray *a2;
mrb_value ary;
mrb_value *ptr;
- int blen;
+ mrb_int blen;
mrb_get_args(mrb, "a", &ptr, &blen);
ary = mrb_ary_new_capa(mrb, a1->len + blen);
@@ -305,7 +303,7 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
mrb_value ary2;
struct RArray *a1, *a2;
mrb_value r = mrb_nil_value();
- int i, len;
+ mrb_int i, len;
mrb_get_args(mrb, "o", &ary2);
if (!mrb_array_p(ary2)) return mrb_nil_value();
@@ -329,7 +327,7 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
}
static void
-ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, int len)
+ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, mrb_int len)
{
ary_modify(mrb, a);
if (a->aux.capa < len)
@@ -429,7 +427,7 @@ mrb_ary_reverse(mrb_state *mrb, mrb_value self)
}
mrb_value
-mrb_ary_new4(mrb_state *mrb, int n, const mrb_value *elts)
+mrb_ary_new4(mrb_state *mrb, mrb_int n, const mrb_value *elts)
{
mrb_value ary;
@@ -443,7 +441,7 @@ mrb_ary_new4(mrb_state *mrb, int n, const mrb_value *elts)
}
mrb_value
-mrb_ary_new_elts(mrb_state *mrb, int n, const mrb_value *elts)
+mrb_ary_new_elts(mrb_state *mrb, mrb_int n, const mrb_value *elts)
{
return mrb_ary_new4(mrb, n, elts);
}
@@ -505,7 +503,7 @@ mrb_ary_shift(mrb_state *mrb, mrb_value self)
}
else {
mrb_value *ptr = a->ptr;
- int size = a->len;
+ mrb_int size = a->len;
val = *ptr;
while((int)(--size)) {
@@ -612,9 +610,9 @@ mrb_value
mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_value rpl)
{
struct RArray *a = mrb_ary_ptr(ary);
- int tail, size;
+ mrb_int tail, size;
mrb_value *argv;
- int i, argc;
+ mrb_int i, argc;
ary_modify(mrb, a);
/* range check */
@@ -660,7 +658,7 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val
return ary;
}
-int
+mrb_int
mrb_ary_len(mrb_state *mrb, mrb_value ary)
{
return RARRAY_LEN(ary);
@@ -677,7 +675,7 @@ mrb_ary_decref(mrb_state *mrb, mrb_shared_array *shared)
}
static mrb_value
-ary_subseq(mrb_state *mrb, struct RArray *a, int beg, int len)
+ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len)
{
struct RArray *b;
@@ -714,7 +712,7 @@ mrb_ary_aget(mrb_state *mrb, mrb_value self)
len = mrb_fixnum(argv[0]);
if (len < 0) return mrb_nil_value();
if (a->len == (int)index) return mrb_ary_new(mrb);
- if ((int)len > a->len - index) len = a->len - index;
+ if (len > a->len - index) len = a->len - index;
return ary_subseq(mrb, a, index, len);
default:
@@ -757,7 +755,7 @@ mrb_ary_delete_at(mrb_state *mrb, mrb_value self)
mrb_int index;
mrb_value val;
mrb_value *ptr;
- int len;
+ mrb_int len;
mrb_get_args(mrb, "i", &index);
if (index < 0) index += a->len;
@@ -803,7 +801,7 @@ mrb_value
mrb_ary_last(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self);
- int size;
+ mrb_int size;
mrb_value *vals;
int len;
@@ -830,7 +828,7 @@ mrb_value
mrb_ary_index_m(mrb_state *mrb, mrb_value self)
{
mrb_value obj;
- int i;
+ mrb_int i;
mrb_get_args(mrb, "o", &obj);
for (i = 0; i < RARRAY_LEN(self); i++) {
@@ -845,7 +843,7 @@ mrb_value
mrb_ary_rindex_m(mrb_state *mrb, mrb_value self)
{
mrb_value obj;
- int i;
+ mrb_int i;
mrb_get_args(mrb, "o", &obj);
for (i = RARRAY_LEN(self) - 1; i >= 0; i--) {
@@ -904,7 +902,7 @@ mrb_check_array_type(mrb_state *mrb, mrb_value ary)
}
mrb_value
-mrb_ary_entry(mrb_value ary, int offset)
+mrb_ary_entry(mrb_value ary, mrb_int offset)
{
if (offset < 0) {
offset += RARRAY_LEN(ary);
@@ -915,7 +913,7 @@ mrb_ary_entry(mrb_value ary, int offset)
static mrb_value
inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list)
{
- int i;
+ mrb_int i;
mrb_value s, arystr;
char head[] = { '[' };
char sep[] = { ',', ' ' };
@@ -934,7 +932,7 @@ inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list)
mrb_str_buf_cat(mrb, arystr, head, sizeof(head));
for(i=0; i<RARRAY_LEN(ary); i++) {
- int ai = mrb_gc_arena_save(mrb);
+ mrb_int ai = mrb_gc_arena_save(mrb);
if (i > 0) {
mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep));
@@ -977,7 +975,7 @@ mrb_ary_inspect(mrb_state *mrb, mrb_value ary)
static mrb_value
join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list)
{
- int i;
+ mrb_int i;
mrb_value result, val, tmp;
/* check recursive */
@@ -1092,7 +1090,7 @@ mrb_ary_equal(mrb_state *mrb, mrb_value ary1)
}
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
else {
- int i;
+ mrb_int i;
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i)))
@@ -1121,11 +1119,11 @@ mrb_ary_eql(mrb_state *mrb, mrb_value ary1)
if (!mrb_array_p(ary2)) return mrb_false_value();
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
else {
- int i;
+ mrb_int i;
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i)))
- return mrb_false_value();
+ return mrb_false_value();
}
return mrb_true_value();
}
diff --git a/src/class.c b/src/class.c
index c0e71dad7..8ea323945 100644
--- a/src/class.c
+++ b/src/class.c
@@ -29,7 +29,7 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
if (kh_exist(h, k)){
struct RProc *m = kh_value(h, k);
if (m) {
- mrb_gc_mark(mrb, (struct RBasic*)m);
+ mrb_gc_mark(mrb, (struct RBasic*)m);
}
}
}
@@ -356,7 +356,7 @@ to_hash(mrb_state *mrb, mrb_value val)
retrieve arguments from mrb_state.
mrb_get_args(mrb, format, ...)
-
+
returns number of arguments parsed.
fortmat specifiers:
@@ -367,7 +367,7 @@ to_hash(mrb_state *mrb, mrb_value val)
H: Hash [mrb_value]
s: String [char*,int]
z: String [char*]
- a: Array [mrb_value*,int]
+ a: Array [mrb_value*,mrb_int]
f: Float [mrb_float]
i: Integer [mrb_int]
b: Binary [int]
@@ -489,10 +489,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value aa;
struct RArray *a;
mrb_value **pb;
- int *pl;
+ mrb_int *pl;
pb = va_arg(ap, mrb_value**);
- pl = va_arg(ap, int*);
+ pl = va_arg(ap, mrb_int*);
if (i < argc) {
aa = to_ary(mrb, *sp++);
a = mrb_ary_ptr(aa);
@@ -774,7 +774,7 @@ mrb_mod_include_p(mrb_state *mrb, mrb_value mod)
}
return mrb_false_value();
}
-
+
static mrb_value
mrb_mod_ancestors(mrb_state *mrb, mrb_value self)
{
diff --git a/src/codegen.c b/src/codegen.c
index ff7e87c28..6f564586c 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -330,7 +330,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
if (c1 == OP_SUB) c = -c;
if (c > 127 || c < -127) break;
- if (0 <= c)
+ if (0 <= c)
s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c);
else
s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c);
@@ -410,9 +410,27 @@ new_lit(codegen_scope *s, mrb_value val)
{
int i;
- for (i=0; i<s->irep->plen; i++) {
- if (mrb_obj_equal(s->mrb, s->irep->pool[i], val)) return i;
+
+ switch (mrb_type(val)) {
+ case MRB_TT_STRING:
+ for (i=0; i<s->irep->plen; i++) {
+ mrb_value pv = s->irep->pool[i];
+ mrb_int len;
+
+ if (mrb_type(pv) != MRB_TT_STRING) continue;
+ if ((len = RSTRING_LEN(pv)) != RSTRING_LEN(val)) continue;
+ if (memcmp(RSTRING_PTR(pv), RSTRING_PTR(val), len) == 0)
+ return i;
+ }
+ break;
+ case MRB_TT_FLOAT:
+ default:
+ for (i=0; i<s->irep->plen; i++) {
+ if (mrb_obj_equal(s->mrb, s->irep->pool[i], val)) return i;
+ }
+ break;
}
+
if (s->irep->plen == s->pcapa) {
s->pcapa *= 2;
s->irep->pool = (mrb_value *)codegen_realloc(s, s->irep->pool, sizeof(mrb_value)*s->pcapa);
@@ -1161,7 +1179,7 @@ codegen(codegen_scope *s, node *tree, int val)
if (e) {
if (val) pop();
pos2 = new_label(s);
- genop(s, MKOP_sBx(OP_JMP, 0));
+ genop(s, MKOP_sBx(OP_JMP, 0));
dispatch(s, pos1);
codegen(s, e, val);
dispatch(s, pos2);
@@ -1902,6 +1920,11 @@ codegen(codegen_scope *s, node *tree, int val)
}
break;
+ case NODE_HEREDOC:
+ /*if(tree == NULL){printf("heredoc error 1\n");exit(11);}*/
+ tree = ((struct mrb_parser_heredoc_info *)tree)->doc;
+ /*if(tree == NULL){printf("heredoc error 2\n");exit(12);}*/
+ /* fall through */
case NODE_DSTR:
if (val) {
node *n = tree;
@@ -1951,7 +1974,7 @@ codegen(codegen_scope *s, node *tree, int val)
pop();
sym = new_sym(s, mrb_intern(s->mrb, "compile"));
genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
- mrb_gc_arena_restore(s->mrb, ai);
+ mrb_gc_arena_restore(s->mrb, ai);
push();
}
break;
@@ -1979,16 +2002,16 @@ codegen(codegen_scope *s, node *tree, int val)
}
n = tree->cdr->cdr;
if (n->car) {
- p = (char*)n->car;
- off = new_lit(s, mrb_str_new(s->mrb, p, strlen(p)));
- codegen(s, tree->car, VAL);
- genop(s, MKOP_ABx(OP_STRING, cursp(), off));
- pop();
- genop(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1));
+ p = (char*)n->car;
+ off = new_lit(s, mrb_str_new(s->mrb, p, strlen(p)));
+ codegen(s, tree->car, VAL);
+ genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+ pop();
+ genop(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1));
}
if (n->cdr) {
- char *p2 = (char*)n->cdr;
- int off;
+ char *p2 = (char*)n->cdr;
+ int off;
push();
off = new_lit(s, mrb_str_new(s->mrb, p2, strlen(p2)));
@@ -1999,7 +2022,7 @@ codegen(codegen_scope *s, node *tree, int val)
pop();
sym = new_sym(s, mrb_intern(s->mrb, "compile"));
genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
- mrb_gc_arena_restore(s->mrb, ai);
+ mrb_gc_arena_restore(s->mrb, ai);
push();
}
else {
@@ -2370,13 +2393,14 @@ codedump(mrb_state *mrb, int n)
{
#ifdef ENABLE_STDIO
mrb_irep *irep = mrb->irep[n];
- int i;
+ int i, ai;
mrb_code c;
if (!irep) return;
printf("irep %d nregs=%d nlocals=%d pools=%d syms=%d\n", n,
irep->nregs, irep->nlocals, irep->plen, irep->slen);
for (i=0; i<irep->ilen; i++) {
+ ai = mrb_gc_arena_save(mrb);
printf("%03d ", i);
c = irep->iseq[i];
switch (GET_OPCODE(c)) {
@@ -2677,6 +2701,7 @@ codedump(mrb_state *mrb, int n)
GETARG_A(c), GETARG_B(c), GETARG_C(c));
break;
}
+ mrb_gc_arena_restore(mrb, ai);
}
printf("\n");
#endif
diff --git a/src/error.c b/src/error.c
index 70a84455f..7599bd0a9 100644
--- a/src/error.c
+++ b/src/error.c
@@ -125,7 +125,7 @@ exc_inspect(mrb_state *mrb, mrb_value exc)
mesg = mrb_attr_get(mrb, exc, mrb_intern(mrb, "mesg"));
file = mrb_attr_get(mrb, exc, mrb_intern(mrb, "file"));
line = mrb_attr_get(mrb, exc, mrb_intern(mrb, "line"));
-
+
if (!mrb_nil_p(file) && !mrb_nil_p(line)) {
str = file;
mrb_str_cat2(mrb, str, ":");
@@ -190,12 +190,12 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc)
ci--;
while (ci >= mrb->cibase) {
if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
- mrb_irep *irep = ci->proc->body.irep;
+ mrb_irep *irep = ci->proc->body.irep;
if (irep->filename && irep->lines && irep->iseq <= pc && pc < irep->iseq + irep->ilen) {
- mrb_obj_iv_set(mrb, exc, mrb_intern(mrb, "file"), mrb_str_new_cstr(mrb, irep->filename));
- mrb_obj_iv_set(mrb, exc, mrb_intern(mrb, "line"), mrb_fixnum_value(irep->lines[pc - irep->iseq - 1]));
- return;
+ mrb_obj_iv_set(mrb, exc, mrb_intern(mrb, "file"), mrb_str_new_cstr(mrb, irep->filename));
+ mrb_obj_iv_set(mrb, exc, mrb_intern(mrb, "line"), mrb_fixnum_value(irep->lines[pc - irep->iseq - 1]));
+ return;
}
}
pc = ci->pc;
@@ -366,14 +366,14 @@ make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr)
n = 1;
exception_call:
{
- mrb_sym exc = mrb_intern(mrb, "exception");
- if (mrb_respond_to(mrb, argv[0], exc)) {
- mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1);
- }
- else {
- /* undef */
- mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
- }
+ mrb_sym exc = mrb_intern(mrb, "exception");
+ if (mrb_respond_to(mrb, argv[0], exc)) {
+ mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1);
+ }
+ else {
+ /* undef */
+ mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
+ }
}
break;
diff --git a/src/gc.c b/src/gc.c
index ae47de025..da6844fa5 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -301,7 +301,7 @@ mrb_free_heap(mrb_state *mrb)
page = page->next;
for (p = tmp->objects, e=p+MRB_HEAP_PAGE_SIZE; p<e; p++) {
if (p->as.free.tt != MRB_TT_FREE)
- obj_free(mrb, &p->as.basic);
+ obj_free(mrb, &p->as.basic);
}
mrb_free(mrb, tmp);
}
@@ -586,7 +586,7 @@ root_scan_phase(mrb_state *mrb)
mrb_irep *irep = mrb->irep[i];
if (!irep) continue;
for (j=0; j<irep->plen; j++) {
- mrb_gc_mark_value(mrb, irep->pool[j]);
+ mrb_gc_mark_value(mrb, irep->pool[j]);
}
}
}
diff --git a/src/hash.c b/src/hash.c
index 2439a235d..728fc0f2f 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -559,7 +559,7 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash)
delVal = mrb_hash_delete_key(mrb, hash, delKey);
mrb_gc_protect(mrb, delVal);
- return mrb_assoc_new(mrb, delKey, delVal);
+ return mrb_assoc_new(mrb, delKey, delVal);
}
}
}
@@ -1119,9 +1119,9 @@ hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql)
key = kh_key(h1,k1);
k2 = kh_get(ht, h2, key);
if (k2 != kh_end(h2)) {
- if (mrb_equal(mrb, kh_value(h1,k1), kh_value(h2,k2))) {
- continue; /* next key */
- }
+ if (mrb_equal(mrb, kh_value(h1,k1), kh_value(h2,k2))) {
+ continue; /* next key */
+ }
}
return mrb_false_value();
}
diff --git a/src/kernel.c b/src/kernel.c
index e45953fd3..7187a125d 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -191,7 +191,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
mrb_sym name;
mrb_value block, *argv;
int argc;
-
+
mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block);
return mrb_funcall_with_block(mrb,self, name, argc, argv, block);
}
@@ -305,7 +305,7 @@ init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj)
case MRB_TT_SCLASS:
case MRB_TT_HASH:
case MRB_TT_DATA:
- mrb_iv_copy(mrb, dest, obj);
+ mrb_iv_copy(mrb, dest, obj);
break;
default:
@@ -483,7 +483,7 @@ mrb_value mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *a
* call-seq:
* obj.instance_eval {| | block } -> obj
*
- * Evaluates the given block,within the context of the receiver (_obj_).
+ * Evaluates the given block,within the context of the receiver (_obj_).
* In order to set the context, the variable +self+ is set to _obj_ while
* the code is executing, giving the code access to _obj_'s
* instance variables. In the version of <code>instance_eval</code>
@@ -913,7 +913,7 @@ mrb_f_raise(mrb_state *mrb, mrb_value self)
{
mrb_value a[2], exc;
int argc;
-
+
argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]);
switch (argc) {
@@ -1108,11 +1108,6 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, ARGS_ANY()); /* 15.3.1.3.45 */
mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, ARGS_NONE()); /* 15.3.1.3.46 */
-#ifdef ENABLE_SPRINTF
- mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, ARGS_ANY()); /* in sprintf.c */
- mrb_define_method(mrb, krn, "format", mrb_f_sprintf, ARGS_ANY()); /* in sprintf.c */
-#endif
-
mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
mrb_alias_method(mrb, mrb->module_class, mrb_intern(mrb, "dup"), mrb_intern(mrb, "clone"));
}
diff --git a/src/load.c b/src/load.c
index 850fa6e8d..84c21c186 100644
--- a/src/load.c
+++ b/src/load.c
@@ -536,7 +536,7 @@ mrb_read_irep(mrb_state *mrb, const char *bin)
nirep = read_rite_header(mrb, src, &bin_header);
if (nirep < 0)
return nirep;
-
+
src += sizeof(bin_header) + MRB_DUMP_SIZE_OF_SHORT; //header + crc
//Read Binary Data Section
diff --git a/src/node.h b/src/node.h
index 284105023..86933c224 100644
--- a/src/node.h
+++ b/src/node.h
@@ -102,5 +102,6 @@ enum node_type {
NODE_IFUNC,
NODE_DSYM,
NODE_ATTRASGN,
+ NODE_HEREDOC,
NODE_LAST
};
diff --git a/src/numeric.c b/src/numeric.c
index b5bff652d..5aa577828 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -306,7 +306,7 @@ static mrb_value
num_eql(mrb_state *mrb, mrb_value x)
{
mrb_value y;
-
+
mrb_get_args(mrb, "o", &y);
if (mrb_type(x) != mrb_type(y)) return mrb_false_value();
if (mrb_equal(mrb, x, y)) {
@@ -699,7 +699,7 @@ mrb_value
mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
{
mrb_int a;
-
+
a = mrb_fixnum(x);
if (a == 0) return x;
if (mrb_fixnum_p(y)) {
@@ -1126,7 +1126,7 @@ mrb_value
mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
{
mrb_int a;
-
+
a = mrb_fixnum(x);
if (a == 0) return y;
if (mrb_fixnum_p(y)) {
@@ -1165,7 +1165,7 @@ mrb_value
mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
{
mrb_int a;
-
+
a = mrb_fixnum(x);
if (mrb_fixnum_p(y)) {
mrb_int b, c;
diff --git a/src/parse.y b/src/parse.y
index 7bca4a4d6..2b09c3e56 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -31,6 +31,7 @@
typedef mrb_ast_node node;
typedef struct mrb_parser_state parser_state;
+typedef struct mrb_parser_heredoc_info parser_heredoc_info;
static int yylex(void *lval, parser_state *p);
static void yyerror(parser_state *p, const char *s);
@@ -736,6 +737,14 @@ new_nth_ref(parser_state *p, int n)
return cons((node*)NODE_NTH_REF, (node*)(intptr_t)n);
}
+// (:heredoc . a)
+static node*
+new_heredoc(parser_state *p)
+{
+ parser_heredoc_info *inf = parser_palloc(p, sizeof(parser_heredoc_info));
+ return cons((node*)NODE_HEREDOC, (node*)inf);
+}
+
static void
new_bv(parser_state *p, mrb_sym id)
{
@@ -757,15 +766,6 @@ call_bin_op(parser_state *p, node *recv, char *m, node *arg1)
return new_call(p, recv, intern(m), list1(list1(arg1)));
}
-/*
-// (:match (a . b))
-static node*
-match_op(parser_state *p, node *a, node *b)
-{
- return cons((node*)NODE_MATCH, cons((node*)a, (node*)b));
-}
-*/
-
static void
args_with_block(parser_state *p, node *a, node *b)
{
@@ -844,10 +844,80 @@ var_reference(parser_state *p, node *lhs)
return lhs;
}
+
+static node*
+heredoc_start_sb(parser_state *p, const char* term, size_t term_len, enum heredoc_type type, int allow_indent)
+{
+ node *newnode = new_heredoc(p);
+ parser_heredoc_info *inf = (parser_heredoc_info*)newnode->cdr;
+ inf->term = term;
+ inf->term_len = term_len;
+ inf->type = type;
+ inf->allow_indent = allow_indent;
+ inf->line_head = TRUE;
+ inf->doc = NULL;
+ p->heredocs = push(p->heredocs, newnode);
+ if (p->parsing_heredoc == NULL) {
+ node *c = p->heredocs;
+ while (c->cdr)
+ c = c->cdr;
+ p->parsing_heredoc = c;
+ }
+ p->heredoc_starts_nextline = TRUE;
+ p->lstate = EXPR_END;
+ return newnode;
+}
+
+static node*
+heredoc_start(parser_state *p, node *beg, node *str, enum heredoc_type type)
+{
+ char *bs = (char*)beg->cdr->car;
+ int allow_indent = (bs[2] == '-');
+ const char *s = (char*)str->cdr->car;
+ size_t len = (intptr_t)str->cdr->cdr;
+ return heredoc_start_sb(p, s, len, type, allow_indent);
+}
+
+static node*
+heredoc_start_sym(parser_state *p, node *beg, mrb_sym sym, enum heredoc_type type)
+{
+ char *bs = (char*)beg->cdr->car;
+ int allow_indent = (bs[2] == '-');
+ int len;
+ const char *s = mrb_sym2name_len(p->mrb, sym, &len);
+ return heredoc_start_sb(p, s, len, type, allow_indent);
+}
+
+parser_heredoc_info *
+parsing_heredoc_inf(parser_state *p)
+{
+ node *nd = p->parsing_heredoc;
+ if (nd == NULL)
+ return NULL;
+ /* assert(nd->car->car == NODE_HEREDOC); */
+ return (parser_heredoc_info*)nd->car->cdr;
+}
+
+static void
+heredoc_end(parser_state *p)
+{
+ p->parsing_heredoc = p->parsing_heredoc->cdr;
+ if (p->parsing_heredoc == NULL) {
+ p->lstate = EXPR_BEG;
+ p->cmd_start = TRUE;
+ p->sterm = 0;
+ p->heredoc_end_now = TRUE;
+ } else {
+ p->sterm = ' '; /* next heredoc */
+ }
+}
+
+
// xxx -----------------------------
%}
+%expect 2
%pure_parser
%parse-param {parser_state *p}
%lex-param {parser_state *p}
@@ -910,11 +980,11 @@ var_reference(parser_state *p, node *lhs)
keyword__FILE__
keyword__ENCODING__
-%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
-%token <nd> tINTEGER tFLOAT tCHAR tREGEXP
-%token <nd> tSTRING tSTRING_PART
-%token <nd> tNTH_REF tBACK_REF
-%token <num> tREGEXP_END
+%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
+%token <nd> tINTEGER tFLOAT tCHAR tREGEXP
+%token <nd> tSTRING tSTRING_PART
+%token <nd> tNTH_REF tBACK_REF
+%token <num> tREGEXP_END
%type <nd> singleton string string_interp regexp
%type <nd> literal numeric cpath symbol
@@ -935,36 +1005,39 @@ var_reference(parser_state *p, node *lhs)
%type <nd> mlhs mlhs_list mlhs_post mlhs_basic mlhs_item mlhs_node mlhs_inner
%type <id> fsym sym basic_symbol operation operation2 operation3
%type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg
-
-%token tUPLUS /* unary+ */
-%token tUMINUS /* unary- */
-%token tPOW /* ** */
-%token tCMP /* <=> */
-%token tEQ /* == */
-%token tEQQ /* === */
-%token tNEQ /* != */
-%token tGEQ /* >= */
-%token tLEQ /* <= */
-%token tANDOP tOROP /* && and || */
-%token tMATCH tNMATCH /* =~ and !~ */
-%token tDOT2 tDOT3 /* .. and ... */
-%token tAREF tASET /* [] and []= */
-%token tLSHFT tRSHFT /* << and >> */
-%token tCOLON2 /* :: */
-%token tCOLON3 /* :: at EXPR_BEG */
-%token <id> tOP_ASGN /* +=, -= etc. */
-%token tASSOC /* => */
-%token tLPAREN /* ( */
-%token tLPAREN_ARG /* ( */
-%token tRPAREN /* ) */
-%token tLBRACK /* [ */
-%token tLBRACE /* { */
-%token tLBRACE_ARG /* { */
-%token tSTAR /* * */
-%token tAMPER /* & */
-%token tLAMBDA /* -> */
+%type <nd> heredoc heredoc_rep heredoc_interp
+
+%token tUPLUS /* unary+ */
+%token tUMINUS /* unary- */
+%token tPOW /* ** */
+%token tCMP /* <=> */
+%token tEQ /* == */
+%token tEQQ /* === */
+%token tNEQ /* != */
+%token tGEQ /* >= */
+%token tLEQ /* <= */
+%token tANDOP tOROP /* && and || */
+%token tMATCH tNMATCH /* =~ and !~ */
+%token tDOT2 tDOT3 /* .. and ... */
+%token tAREF tASET /* [] and []= */
+%token tLSHFT tRSHFT /* << and >> */
+%token tCOLON2 /* :: */
+%token tCOLON3 /* :: at EXPR_BEG */
+%token <id> tOP_ASGN /* +=, -= etc. */
+%token tASSOC /* => */
+%token tLPAREN /* ( */
+%token tLPAREN_ARG /* ( */
+%token tRPAREN /* ) */
+%token tLBRACK /* [ */
+%token tLBRACE /* { */
+%token tLBRACE_ARG /* { */
+%token tSTAR /* * */
+%token tAMPER /* & */
+%token tLAMBDA /* -> */
%token tSYMBEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG
%token tSTRING_BEG tSTRING_DVAR tLAMBEG
+%token <nd> tHEREDOC_BEG /* <<, <<- */
+%token tHEREDOC_END
/*
* precedence table
@@ -1871,6 +1944,7 @@ mrhs : args ',' arg_value
primary : literal
| string
| regexp
+ | heredoc
| var_ref
| backref
| tFID
@@ -2523,6 +2597,71 @@ regexp : tREGEXP_BEG tREGEXP
}
;
+heredoc : tHEREDOC_BEG tSTRING_BEG tSTRING
+ {
+ $$ = heredoc_start(p, $1, $3, heredoc_type_norm);
+ }
+ | tHEREDOC_BEG tSTRING
+ {
+ $$ = heredoc_start(p, $1, $2, heredoc_type_quote);
+ }
+ | tHEREDOC_BEG tIDENTIFIER
+ {
+ $$ = heredoc_start_sym(p, $1, $2, heredoc_type_norm);
+ }
+ | tHEREDOC_BEG tCONSTANT
+ {
+ $$ = heredoc_start_sym(p, $1, $2, heredoc_type_norm);
+ }
+ ;
+
+
+opt_heredoc_bodies : none
+ | heredoc_bodies
+ ;
+
+heredoc_bodies : heredoc_body
+ | heredoc_bodies heredoc_body
+ ;
+
+heredoc_body : tHEREDOC_END
+ {
+ /* assert(parsing_heredoc_inf(p) != NULL); */
+ parsing_heredoc_inf(p)->doc = list1(new_str(p, "", 0));
+ heredoc_end(p);
+ }
+ | heredoc_rep tHEREDOC_END
+ {
+ /* assert(parsing_heredoc_inf(p) != NULL); */
+ parsing_heredoc_inf(p)->doc = $1;
+ heredoc_end(p);
+ }
+ ;
+
+heredoc_rep : heredoc_interp
+ | heredoc_rep heredoc_interp
+ {
+ $$ = append($1, $2);
+ }
+ ;
+
+heredoc_interp : tSTRING
+ {
+ $$ = list1($1);
+ }
+ | tSTRING_PART
+ {
+ $<num>$ = p->sterm;
+ p->sterm = 0;
+ }
+ compstmt
+ '}'
+ {
+ p->sterm = $<num>2;
+ $$ = list2($1, $3);
+ }
+ ;
+
symbol : basic_symbol
{
$$ = new_sym(p, $1);
@@ -2873,6 +3012,7 @@ singleton : var_ref
case NODE_MATCH:
case NODE_FLOAT:
case NODE_ARRAY:
+ case NODE_HEREDOC:
yyerror(p, "can't define singleton method for literals");
default:
break;
@@ -2957,6 +3097,7 @@ nl : '\n'
p->lineno++;
p->column = 0;
}
+ opt_heredoc_bodies
terms : term
| terms ';' {yyerrok;}
@@ -3092,9 +3233,7 @@ nextc(parser_state *p)
else {
c = (unsigned char)*p->s++;
}
- if (c == '\n') {
- // must understand heredoc
- }
+ /* if (c == '\n') { } */ /* heredoc treated in parser_yylex() */
}
p->column++;
return c;
@@ -3324,12 +3463,12 @@ read_escape(parser_state *p)
buf[0] = c;
for (i=1; i<3; i++) {
- buf[i] = nextc(p);
- if (buf[i] == -1) goto eof;
- if (buf[i] < '0' || '7' < buf[i]) {
- pushback(p, buf[i]);
- break;
- }
+ buf[i] = nextc(p);
+ if (buf[i] == -1) goto eof;
+ if (buf[i] < '0' || '7' < buf[i]) {
+ pushback(p, buf[i]);
+ break;
+ }
}
c = scan_oct(buf, i, &i);
}
@@ -3341,17 +3480,17 @@ read_escape(parser_state *p)
int i;
for (i=0; i<2; i++) {
- buf[i] = nextc(p);
- if (buf[i] == -1) goto eof;
- if (!isxdigit(buf[i])) {
- pushback(p, buf[i]);
- break;
- }
+ buf[i] = nextc(p);
+ if (buf[i] == -1) goto eof;
+ if (!isxdigit(buf[i])) {
+ pushback(p, buf[i]);
+ break;
+ }
}
c = scan_hex(buf, i, &i);
if (i == 0) {
- yyerror(p, "Invalid escape character syntax");
- return 0;
+ yyerror(p, "Invalid escape character syntax");
+ return 0;
}
}
return c;
@@ -3426,23 +3565,23 @@ parse_string(parser_state *p, int term)
else if (c == '\\') {
c = nextc(p);
if (c == term) {
- tokadd(p, c);
+ tokadd(p, c);
}
else {
- pushback(p, c);
- tokadd(p, read_escape(p));
+ pushback(p, c);
+ tokadd(p, read_escape(p));
}
continue;
}
if (c == '#') {
c = nextc(p);
if (c == '{') {
- tokfix(p);
- p->lstate = EXPR_BEG;
- p->sterm = term;
- p->cmd_start = TRUE;
- yylval.nd = new_str(p, tok(p), toklen(p));
- return tSTRING_PART;
+ tokfix(p);
+ p->lstate = EXPR_BEG;
+ p->sterm = term;
+ p->cmd_start = TRUE;
+ yylval.nd = new_str(p, tok(p), toklen(p));
+ return tSTRING_PART;
}
tokadd(p, '#');
pushback(p, c);
@@ -3548,6 +3687,73 @@ parse_qstring(parser_state *p, int beg, int end)
}
static int
+parse_heredoc_line(parser_state *p)
+{
+ parser_heredoc_info *inf = parsing_heredoc_inf(p);
+ /* assert(inf != NULL); */
+ int c;
+ int line_head;
+
+ newtok(p);
+ while ((c = nextc(p)) != '\n') {
+ if (c == -1)
+ break;
+ if (inf->type != heredoc_type_quote) {
+ if (c == '\\') {
+ tokadd(p, read_escape(p));
+ inf->line_head = FALSE;
+ continue;
+ }
+ if (c == '#') {
+ c = nextc(p);
+ if (c == '{') {
+ tokfix(p);
+ p->lstate = EXPR_BEG;
+ p->sterm = ' ';
+ p->cmd_start = TRUE;
+ yylval.nd = new_str(p, tok(p), toklen(p));
+ inf->line_head = FALSE;
+ return tSTRING_PART;
+ }
+ tokadd(p, '#');
+ pushback(p, c);
+ continue;
+ }
+ }
+ tokadd(p, c);
+ }
+ tokadd(p, '\n');
+ tokfix(p);
+ p->lineno++;
+ p->column = 0;
+ line_head = inf->line_head;
+ inf->line_head = TRUE;
+ if (line_head) {
+ /* check whether end of heredoc */
+ const char *s = tok(p);
+ int len = toklen(p);
+ if (inf->allow_indent) {
+ while (ISSPACE(*s) && len > 0) {
+ ++s;
+ --len;
+ }
+ }
+ if ((len-1 == inf->term_len) && (strncmp(s, inf->term, len-1) == 0)) {
+ return tHEREDOC_END;
+ }
+ }
+ if (c == -1) {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "can't find string \"%s\" anywhere before EOF", inf->term);
+ yyerror(p, buf);
+ return 0;
+ }
+
+ yylval.nd = new_str(p, tok(p), toklen(p));
+ return tSTRING;
+}
+
+static int
arg_ambiguous(parser_state *p)
{
yywarning(p, "ambiguous first argument; put parentheses or even spaces");
@@ -3560,11 +3766,15 @@ static int
parser_yylex(parser_state *p)
{
register int c;
+ int c2;
int space_seen = 0;
int cmd_state;
enum mrb_lex_state_enum last_state;
int token_column;
+ if ((p->sterm == ' ') && (p->parsing_heredoc != NULL) && (! p->heredoc_starts_nextline)) {
+ return parse_heredoc_line(p);
+ }
if (p->sterm) {
return parse_string(p, p->sterm);
}
@@ -3573,22 +3783,27 @@ parser_yylex(parser_state *p)
retry:
last_state = p->lstate;
switch (c = nextc(p)) {
- case '\0': /* NUL */
- case '\004': /* ^D */
- case '\032': /* ^Z */
- case -1: /* end of script. */
+ case '\0': /* NUL */
+ case '\004': /* ^D */
+ case '\032': /* ^Z */
+ case -1: /* end of script. */
return 0;
- /* white spaces */
+ /* white spaces */
case ' ': case '\t': case '\f': case '\r':
- case '\13': /* '\v' */
+ case '\13': /* '\v' */
space_seen = 1;
goto retry;
- case '#': /* it's a comment */
+ case '#': /* it's a comment */
skip(p, '\n');
- /* fall through */
+ /* fall through */
case '\n':
+ p->heredoc_starts_nextline = FALSE;
+ if (p->parsing_heredoc != NULL) {
+ p->sterm = ' ';
+ goto normal_newline;
+ }
switch (p->lstate) {
case EXPR_BEG:
case EXPR_FNAME:
@@ -3605,19 +3820,19 @@ parser_yylex(parser_state *p)
switch (c) {
case ' ': case '\t': case '\f': case '\r':
case '\13': /* '\v' */
- space_seen = 1;
- break;
+ space_seen = 1;
+ break;
case '.':
- if ((c = nextc(p)) != '.') {
- pushback(p, c);
- pushback(p, '.');
- goto retry;
- }
+ if ((c = nextc(p)) != '.') {
+ pushback(p, c);
+ pushback(p, '.');
+ goto retry;
+ }
case -1: /* EOF */
- goto normal_newline;
+ goto normal_newline;
default:
- pushback(p, c);
- goto normal_newline;
+ pushback(p, c);
+ goto normal_newline;
}
}
normal_newline:
@@ -3628,29 +3843,29 @@ parser_yylex(parser_state *p)
case '*':
if ((c = nextc(p)) == '*') {
if ((c = nextc(p)) == '=') {
- yylval.id = intern("**");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern("**");
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
c = tPOW;
}
else {
if (c == '=') {
- yylval.id = intern("*");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern("*");
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
if (IS_SPCARG(c)) {
- yywarning(p, "`*' interpreted as argument prefix");
- c = tSTAR;
+ yywarning(p, "`*' interpreted as argument prefix");
+ c = tSTAR;
}
else if (IS_BEG()) {
- c = tSTAR;
+ c = tSTAR;
}
else {
- c = '*';
+ c = '*';
}
}
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
@@ -3665,7 +3880,7 @@ parser_yylex(parser_state *p)
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
p->lstate = EXPR_ARG;
if (c == '@') {
- return '!';
+ return '!';
}
}
else {
@@ -3683,8 +3898,8 @@ parser_yylex(parser_state *p)
case '=':
if (p->column == 1) {
if (peeks(p, "begin\n")) {
- skips(p, "\n=end\n");
- goto retry;
+ skips(p, "\n=end\n");
+ goto retry;
}
}
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
@@ -3694,7 +3909,7 @@ parser_yylex(parser_state *p)
}
if ((c = nextc(p)) == '=') {
if ((c = nextc(p)) == '=') {
- return tEQQ;
+ return tEQQ;
}
pushback(p, c);
return tEQ;
@@ -3711,17 +3926,26 @@ parser_yylex(parser_state *p)
case '<':
last_state = p->lstate;
c = nextc(p);
-#if 0
- // no heredoc supported yet
if (c == '<' &&
- p->lstate != EXPR_DOT &&
- p->lstate != EXPR_CLASS &&
- !IS_END() &&
- (!IS_ARG() || space_seen)) {
- int token = heredoc_identifier();
- if (token) return token;
+ p->lstate != EXPR_DOT &&
+ p->lstate != EXPR_CLASS &&
+ !IS_END() &&
+ (!IS_ARG() || space_seen)) {
+ /* heredocument check */
+ newtok(p); tokadd(p, '<'); tokadd(p, '<');
+ c2 = nextc(p);
+ if (c2 == '-') {
+ tokadd(p, c2);
+ c2 = nextc(p);
+ }
+ pushback(p, c2);
+ if (!ISSPACE(c2)) {
+ tokfix(p);
+ yylval.nd = new_str(p, tok(p), toklen(p));
+ p->lstate = EXPR_DOT;
+ return tHEREDOC_BEG;
+ }
}
-#endif
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
p->lstate = EXPR_ARG;
} else {
@@ -3732,16 +3956,16 @@ parser_yylex(parser_state *p)
}
if (c == '=') {
if ((c = nextc(p)) == '>') {
- return tCMP;
+ return tCMP;
}
pushback(p, c);
return tLEQ;
}
if (c == '<') {
if ((c = nextc(p)) == '=') {
- yylval.id = intern("<<");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern("<<");
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
return tLSHFT;
@@ -3760,9 +3984,9 @@ parser_yylex(parser_state *p)
}
if (c == '>') {
if ((c = nextc(p)) == '=') {
- yylval.id = intern(">>");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern(">>");
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
return tRSHFT;
@@ -3789,35 +4013,35 @@ parser_yylex(parser_state *p)
}
if (isspace(c)) {
if (!IS_ARG()) {
- int c2;
- switch (c) {
- case ' ':
- c2 = 's';
- break;
- case '\n':
- c2 = 'n';
- break;
- case '\t':
- c2 = 't';
- break;
- case '\v':
- c2 = 'v';
- break;
- case '\r':
- c2 = 'r';
- break;
- case '\f':
- c2 = 'f';
- break;
- default:
- c2 = 0;
- break;
- }
- if (c2) {
- char buf[256];
- snprintf(buf, sizeof(buf), "invalid character syntax; use ?\\%c", c2);
- yyerror(p, buf);
- }
+ int c2;
+ switch (c) {
+ case ' ':
+ c2 = 's';
+ break;
+ case '\n':
+ c2 = 'n';
+ break;
+ case '\t':
+ c2 = 't';
+ break;
+ case '\v':
+ c2 = 'v';
+ break;
+ case '\r':
+ c2 = 'r';
+ break;
+ case '\f':
+ c2 = 'f';
+ break;
+ default:
+ c2 = 0;
+ break;
+ }
+ if (c2) {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "invalid character syntax; use ?\\%c", c2);
+ yyerror(p, buf);
+ }
}
ternary:
pushback(p, c);
@@ -3830,20 +4054,20 @@ parser_yylex(parser_state *p)
int c2 = nextc(p);
pushback(p, c2);
if ((isalnum(c2) || c2 == '_')) {
- goto ternary;
+ goto ternary;
}
}
if (c == '\\') {
c = nextc(p);
if (c == 'u') {
#if 0
- tokadd_utf8(p);
+ tokadd_utf8(p);
#endif
}
else {
- pushback(p, c);
- c = read_escape(p);
- tokadd(p, c);
+ pushback(p, c);
+ c = read_escape(p);
+ tokadd(p, c);
}
}
else {
@@ -3858,9 +4082,9 @@ parser_yylex(parser_state *p)
if ((c = nextc(p)) == '&') {
p->lstate = EXPR_BEG;
if ((c = nextc(p)) == '=') {
- yylval.id = intern("&&");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern("&&");
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
return tANDOP;
@@ -3892,9 +4116,9 @@ parser_yylex(parser_state *p)
if ((c = nextc(p)) == '|') {
p->lstate = EXPR_BEG;
if ((c = nextc(p)) == '=') {
- yylval.id = intern("||");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern("||");
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
return tOROP;
@@ -3918,7 +4142,7 @@ parser_yylex(parser_state *p)
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
p->lstate = EXPR_ARG;
if (c == '@') {
- return tUPLUS;
+ return tUPLUS;
}
pushback(p, c);
return '+';
@@ -3932,8 +4156,8 @@ parser_yylex(parser_state *p)
p->lstate = EXPR_BEG;
pushback(p, c);
if (c != -1 && ISDIGIT(c)) {
- c = '+';
- goto start_num;
+ c = '+';
+ goto start_num;
}
return tUPLUS;
}
@@ -3946,7 +4170,7 @@ parser_yylex(parser_state *p)
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
p->lstate = EXPR_ARG;
if (c == '@') {
- return tUMINUS;
+ return tUMINUS;
}
pushback(p, c);
return '-';
@@ -3964,7 +4188,7 @@ parser_yylex(parser_state *p)
p->lstate = EXPR_BEG;
pushback(p, c);
if (c != -1 && ISDIGIT(c)) {
- return tUMINUS_NUM;
+ return tUMINUS_NUM;
}
return tUMINUS;
}
@@ -3976,7 +4200,7 @@ parser_yylex(parser_state *p)
p->lstate = EXPR_BEG;
if ((c = nextc(p)) == '.') {
if ((c = nextc(p)) == '.') {
- return tDOT3;
+ return tDOT3;
}
pushback(p, c);
return tDOT2;
@@ -3993,223 +4217,223 @@ parser_yylex(parser_state *p)
case '5': case '6': case '7': case '8': case '9':
{
int is_float, seen_point, seen_e, nondigit;
-
+
is_float = seen_point = seen_e = nondigit = 0;
p->lstate = EXPR_END;
token_column = newtok(p);
if (c == '-' || c == '+') {
- tokadd(p, c);
- c = nextc(p);
+ tokadd(p, c);
+ c = nextc(p);
}
if (c == '0') {
#define no_digits() do {yyerror(p,"numeric literal without digits"); return 0;} while (0)
- int start = toklen(p);
- c = nextc(p);
- if (c == 'x' || c == 'X') {
- /* hexadecimal */
- c = nextc(p);
- if (c != -1 && ISXDIGIT(c)) {
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (!ISXDIGIT(c)) break;
- nondigit = 0;
- tokadd(p, tolower(c));
- } while ((c = nextc(p)) != -1);
- }
- pushback(p, c);
- tokfix(p);
- if (toklen(p) == start) {
- no_digits();
- }
- else if (nondigit) goto trailing_uc;
- yylval.nd = new_int(p, tok(p), 16);
- return tINTEGER;
- }
- if (c == 'b' || c == 'B') {
- /* binary */
- c = nextc(p);
- if (c == '0' || c == '1') {
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (c != '0' && c != '1') break;
- nondigit = 0;
- tokadd(p, c);
- } while ((c = nextc(p)) != -1);
- }
- pushback(p, c);
- tokfix(p);
- if (toklen(p) == start) {
- no_digits();
- }
- else if (nondigit) goto trailing_uc;
- yylval.nd = new_int(p, tok(p), 2);
- return tINTEGER;
- }
- if (c == 'd' || c == 'D') {
- /* decimal */
- c = nextc(p);
- if (c != -1 && ISDIGIT(c)) {
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (!ISDIGIT(c)) break;
- nondigit = 0;
- tokadd(p, c);
- } while ((c = nextc(p)) != -1);
- }
- pushback(p, c);
- tokfix(p);
- if (toklen(p) == start) {
- no_digits();
- }
- else if (nondigit) goto trailing_uc;
- yylval.nd = new_int(p, tok(p), 10);
- return tINTEGER;
- }
- if (c == '_') {
- /* 0_0 */
- goto octal_number;
- }
- if (c == 'o' || c == 'O') {
- /* prefixed octal */
- c = nextc(p);
- if (c == -1 || c == '_' || !ISDIGIT(c)) {
- no_digits();
- }
- }
- if (c >= '0' && c <= '7') {
- /* octal */
- octal_number:
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (c < '0' || c > '9') break;
- if (c > '7') goto invalid_octal;
- nondigit = 0;
- tokadd(p, c);
- } while ((c = nextc(p)) != -1);
-
- if (toklen(p) > start) {
- pushback(p, c);
- tokfix(p);
- if (nondigit) goto trailing_uc;
- yylval.nd = new_int(p, tok(p), 8);
- return tINTEGER;
- }
- if (nondigit) {
- pushback(p, c);
- goto trailing_uc;
- }
- }
- if (c > '7' && c <= '9') {
- invalid_octal:
- yyerror(p, "Invalid octal digit");
- }
- else if (c == '.' || c == 'e' || c == 'E') {
- tokadd(p, '0');
- }
- else {
- pushback(p, c);
- yylval.nd = new_int(p, "0", 10);
- return tINTEGER;
- }
+ int start = toklen(p);
+ c = nextc(p);
+ if (c == 'x' || c == 'X') {
+ /* hexadecimal */
+ c = nextc(p);
+ if (c != -1 && ISXDIGIT(c)) {
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (!ISXDIGIT(c)) break;
+ nondigit = 0;
+ tokadd(p, tolower(c));
+ } while ((c = nextc(p)) != -1);
+ }
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ no_digits();
+ }
+ else if (nondigit) goto trailing_uc;
+ yylval.nd = new_int(p, tok(p), 16);
+ return tINTEGER;
+ }
+ if (c == 'b' || c == 'B') {
+ /* binary */
+ c = nextc(p);
+ if (c == '0' || c == '1') {
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (c != '0' && c != '1') break;
+ nondigit = 0;
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
+ }
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ no_digits();
+ }
+ else if (nondigit) goto trailing_uc;
+ yylval.nd = new_int(p, tok(p), 2);
+ return tINTEGER;
+ }
+ if (c == 'd' || c == 'D') {
+ /* decimal */
+ c = nextc(p);
+ if (c != -1 && ISDIGIT(c)) {
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (!ISDIGIT(c)) break;
+ nondigit = 0;
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
+ }
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ no_digits();
+ }
+ else if (nondigit) goto trailing_uc;
+ yylval.nd = new_int(p, tok(p), 10);
+ return tINTEGER;
+ }
+ if (c == '_') {
+ /* 0_0 */
+ goto octal_number;
+ }
+ if (c == 'o' || c == 'O') {
+ /* prefixed octal */
+ c = nextc(p);
+ if (c == -1 || c == '_' || !ISDIGIT(c)) {
+ no_digits();
+ }
+ }
+ if (c >= '0' && c <= '7') {
+ /* octal */
+ octal_number:
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (c < '0' || c > '9') break;
+ if (c > '7') goto invalid_octal;
+ nondigit = 0;
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
+
+ if (toklen(p) > start) {
+ pushback(p, c);
+ tokfix(p);
+ if (nondigit) goto trailing_uc;
+ yylval.nd = new_int(p, tok(p), 8);
+ return tINTEGER;
+ }
+ if (nondigit) {
+ pushback(p, c);
+ goto trailing_uc;
+ }
+ }
+ if (c > '7' && c <= '9') {
+ invalid_octal:
+ yyerror(p, "Invalid octal digit");
+ }
+ else if (c == '.' || c == 'e' || c == 'E') {
+ tokadd(p, '0');
+ }
+ else {
+ pushback(p, c);
+ yylval.nd = new_int(p, "0", 10);
+ return tINTEGER;
+ }
}
for (;;) {
- switch (c) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- nondigit = 0;
- tokadd(p, c);
- break;
-
- case '.':
- if (nondigit) goto trailing_uc;
- if (seen_point || seen_e) {
- goto decode_num;
- }
- else {
- int c0 = nextc(p);
- if (c0 == -1 || !ISDIGIT(c0)) {
- pushback(p, c0);
- goto decode_num;
- }
- c = c0;
- }
- tokadd(p, '.');
- tokadd(p, c);
- is_float++;
- seen_point++;
- nondigit = 0;
- break;
-
- case 'e':
- case 'E':
- if (nondigit) {
- pushback(p, c);
- c = nondigit;
- goto decode_num;
- }
- if (seen_e) {
- goto decode_num;
- }
- tokadd(p, c);
- seen_e++;
- is_float++;
- nondigit = c;
- c = nextc(p);
- if (c != '-' && c != '+') continue;
- tokadd(p, c);
- nondigit = c;
- break;
-
- case '_': /* `_' in number just ignored */
- if (nondigit) goto decode_num;
- nondigit = c;
- break;
-
- default:
- goto decode_num;
- }
- c = nextc(p);
+ switch (c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ nondigit = 0;
+ tokadd(p, c);
+ break;
+
+ case '.':
+ if (nondigit) goto trailing_uc;
+ if (seen_point || seen_e) {
+ goto decode_num;
+ }
+ else {
+ int c0 = nextc(p);
+ if (c0 == -1 || !ISDIGIT(c0)) {
+ pushback(p, c0);
+ goto decode_num;
+ }
+ c = c0;
+ }
+ tokadd(p, '.');
+ tokadd(p, c);
+ is_float++;
+ seen_point++;
+ nondigit = 0;
+ break;
+
+ case 'e':
+ case 'E':
+ if (nondigit) {
+ pushback(p, c);
+ c = nondigit;
+ goto decode_num;
+ }
+ if (seen_e) {
+ goto decode_num;
+ }
+ tokadd(p, c);
+ seen_e++;
+ is_float++;
+ nondigit = c;
+ c = nextc(p);
+ if (c != '-' && c != '+') continue;
+ tokadd(p, c);
+ nondigit = c;
+ break;
+
+ case '_': /* `_' in number just ignored */
+ if (nondigit) goto decode_num;
+ nondigit = c;
+ break;
+
+ default:
+ goto decode_num;
+ }
+ c = nextc(p);
}
decode_num:
pushback(p, c);
if (nondigit) {
trailing_uc:
- yyerror_i(p, "trailing `%c' in number", nondigit);
+ yyerror_i(p, "trailing `%c' in number", nondigit);
}
tokfix(p);
if (is_float) {
- double d;
- char *endp;
-
- errno = 0;
- d = strtod(tok(p), &endp);
- if (d == 0 && endp == tok(p)) {
- yywarning_s(p, "corrupted float value %s", tok(p));
- }
- else if (errno == ERANGE) {
- yywarning_s(p, "float %s out of range", tok(p));
- errno = 0;
- }
- yylval.nd = new_float(p, tok(p));
- return tFLOAT;
+ double d;
+ char *endp;
+
+ errno = 0;
+ d = strtod(tok(p), &endp);
+ if (d == 0 && endp == tok(p)) {
+ yywarning_s(p, "corrupted float value %s", tok(p));
+ }
+ else if (errno == ERANGE) {
+ yywarning_s(p, "float %s out of range", tok(p));
+ errno = 0;
+ }
+ yylval.nd = new_float(p, tok(p));
+ return tFLOAT;
}
yylval.nd = new_int(p, tok(p), 10);
return tINTEGER;
@@ -4231,8 +4455,8 @@ parser_yylex(parser_state *p)
c = nextc(p);
if (c == ':') {
if (IS_BEG() || p->lstate == EXPR_CLASS || IS_SPCARG(-1)) {
- p->lstate = EXPR_BEG;
- return tCOLON3;
+ p->lstate = EXPR_BEG;
+ return tCOLON3;
}
p->lstate = EXPR_DOT;
return tCOLON2;
@@ -4294,7 +4518,7 @@ parser_yylex(parser_state *p)
case ';':
p->lstate = EXPR_BEG;
return ';';
-
+
case ',':
p->lstate = EXPR_BEG;
return ',';
@@ -4302,7 +4526,7 @@ parser_yylex(parser_state *p)
case '~':
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
if ((c = nextc(p)) != '@') {
- pushback(p, c);
+ pushback(p, c);
}
p->lstate = EXPR_ARG;
}
@@ -4329,11 +4553,11 @@ parser_yylex(parser_state *p)
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
p->lstate = EXPR_ARG;
if ((c = nextc(p)) == ']') {
- if ((c = nextc(p)) == '=') {
- return tASET;
- }
- pushback(p, c);
- return tAREF;
+ if ((c = nextc(p)) == '=') {
+ return tASET;
+ }
+ pushback(p, c);
+ return tAREF;
}
pushback(p, c);
return '[';
@@ -4390,19 +4614,19 @@ parser_yylex(parser_state *p)
c = nextc(p);
quotation:
if (c == -1 || !ISALNUM(c)) {
- term = c;
- c = 'Q';
+ term = c;
+ c = 'Q';
}
else {
- beg = term = nextc(p);
- if (isalnum(term)) {
- yyerror(p, "unknown type of %string");
- return 0;
- }
+ beg = term = nextc(p);
+ if (isalnum(term)) {
+ yyerror(p, "unknown type of %string");
+ return 0;
+ }
}
if (c == -1 || term == -1) {
- yyerror(p, "unterminated quoted string meets end of file");
- return 0;
+ yyerror(p, "unterminated quoted string meets end of file");
+ return 0;
}
#if 0
paren = term;
@@ -4419,51 +4643,51 @@ parser_yylex(parser_state *p)
switch (c) {
case 'Q':
#if 0
- p->lex_strterm = new_strterm(p, str_dquote, term, paren);
+ p->lex_strterm = new_strterm(p, str_dquote, term, paren);
#endif
- return tSTRING_BEG;
+ return tSTRING_BEG;
case 'q':
#if 0
- p->lex_strterm = new_strterm(p, str_squote, term, paren);
+ p->lex_strterm = new_strterm(p, str_squote, term, paren);
#endif
- p->sterm = 0;
- return parse_qstring(p, beg, term);
+ p->sterm = 0;
+ return parse_qstring(p, beg, term);
case 'W':
#if 0
- p->lex_strterm = new_strterm(p, str_dword, term, paren);
+ p->lex_strterm = new_strterm(p, str_dword, term, paren);
#endif
- do {c = nextc(p);} while (isspace(c));
- pushback(p, c);
- return tWORDS_BEG;
+ do {c = nextc(p);} while (isspace(c));
+ pushback(p, c);
+ return tWORDS_BEG;
case 'w':
#if 0
- p->lex_strterm = new_strterm(p, str_sword, term, paren);
+ p->lex_strterm = new_strterm(p, str_sword, term, paren);
#endif
- do {c = nextc(p);} while (isspace(c));
- pushback(p, c);
- return tQWORDS_BEG;
+ do {c = nextc(p);} while (isspace(c));
+ pushback(p, c);
+ return tQWORDS_BEG;
case 'r':
#if 0
- p->lex_strterm = new_strterm(p, str_regexp, term, paren);
+ p->lex_strterm = new_strterm(p, str_regexp, term, paren);
#endif
- p->regexp = 1;
- p->sterm = term;
- return tREGEXP_BEG;
+ p->regexp = 1;
+ p->sterm = term;
+ return tREGEXP_BEG;
case 's':
#if 0
- p->lex_strterm = new_strterm(p, str_ssym, term, paren);
+ p->lex_strterm = new_strterm(p, str_ssym, term, paren);
#endif
- p->lstate = EXPR_FNAME;
- return tSYMBEG;
+ p->lstate = EXPR_FNAME;
+ return tSYMBEG;
default:
- yyerror(p, "unknown type of %string");
- return 0;
+ yyerror(p, "unknown type of %string");
+ return 0;
}
}
if ((c = nextc(p)) == '=') {
@@ -4487,27 +4711,27 @@ parser_yylex(parser_state *p)
token_column = newtok(p);
c = nextc(p);
switch (c) {
- case '_': /* $_: last read line string */
+ case '_': /* $_: last read line string */
c = nextc(p);
pushback(p, c);
c = '_';
/* fall through */
- case '~': /* $~: match-data */
- case '*': /* $*: argv */
- case '$': /* $$: pid */
- case '?': /* $?: last status */
- case '!': /* $!: error string */
- case '@': /* $@: error position */
- case '/': /* $/: input record separator */
- case '\\': /* $\: output record separator */
- case ';': /* $;: field separator */
- case ',': /* $,: output field separator */
- case '.': /* $.: last read line number */
- case '=': /* $=: ignorecase */
- case ':': /* $:: load path */
- case '<': /* $<: reading filename */
- case '>': /* $>: default output handle */
- case '\"': /* $": already loaded files */
+ case '~': /* $~: match-data */
+ case '*': /* $*: argv */
+ case '$': /* $$: pid */
+ case '?': /* $?: last status */
+ case '!': /* $!: error string */
+ case '@': /* $@: error position */
+ case '/': /* $/: input record separator */
+ case '\\': /* $\: output record separator */
+ case ';': /* $;: field separator */
+ case ',': /* $,: output field separator */
+ case '.': /* $.: last read line number */
+ case '=': /* $=: ignorecase */
+ case ':': /* $:: load path */
+ case '<': /* $<: reading filename */
+ case '>': /* $>: default output handle */
+ case '\"': /* $": already loaded files */
tokadd(p, '$');
tokadd(p, c);
tokfix(p);
@@ -4524,14 +4748,14 @@ parser_yylex(parser_state *p)
yylval.id = intern(tok(p));
return tGVAR;
- case '&': /* $&: last match */
- case '`': /* $`: string before last match */
- case '\'': /* $': string after last match */
- case '+': /* $+: string matches last paren. */
+ case '&': /* $&: last match */
+ case '`': /* $`: string before last match */
+ case '\'': /* $': string after last match */
+ case '+': /* $+: string matches last pattern */
if (last_state == EXPR_FNAME) {
- tokadd(p, '$');
- tokadd(p, c);
- goto gvar;
+ tokadd(p, '$');
+ tokadd(p, c);
+ goto gvar;
}
yylval.nd = new_back_ref(p, c);
return tBACK_REF;
@@ -4540,8 +4764,8 @@ parser_yylex(parser_state *p)
case '4': case '5': case '6':
case '7': case '8': case '9':
do {
- tokadd(p, c);
- c = nextc(p);
+ tokadd(p, c);
+ c = nextc(p);
} while (c != -1 && isdigit(c));
pushback(p, c);
if (last_state == EXPR_FNAME) goto gvar;
@@ -4551,8 +4775,8 @@ parser_yylex(parser_state *p)
default:
if (!identchar(c)) {
- pushback(p, c);
- return '$';
+ pushback(p, c);
+ return '$';
}
case '0':
tokadd(p, '$');
@@ -4569,10 +4793,10 @@ parser_yylex(parser_state *p)
}
if (c != -1 && isdigit(c)) {
if (p->bidx == 1) {
- yyerror_i(p, "`@%c' is not allowed as an instance variable name", c);
+ yyerror_i(p, "`@%c' is not allowed as an instance variable name", c);
}
else {
- yyerror_i(p, "`@@%c' is not allowed as a class variable name", c);
+ yyerror_i(p, "`@@%c' is not allowed as a class variable name", c);
}
return 0;
}
@@ -4630,97 +4854,95 @@ parser_yylex(parser_state *p)
case '@':
p->lstate = EXPR_END;
if (tok(p)[1] == '@')
- result = tCVAR;
+ result = tCVAR;
else
- result = tIVAR;
+ result = tIVAR;
break;
default:
if (toklast(p) == '!' || toklast(p) == '?') {
- result = tFID;
+ result = tFID;
}
else {
- if (p->lstate == EXPR_FNAME) {
- if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
- (!peek(p, '=') || (peek_n(p, '>', 1)))) {
- result = tIDENTIFIER;
- tokadd(p, c);
- tokfix(p);
- }
- else {
- pushback(p, c);
- }
- }
- if (result == 0 && isupper((int)tok(p)[0])) {
- result = tCONSTANT;
- }
- else {
- result = tIDENTIFIER;
- }
+ if (p->lstate == EXPR_FNAME) {
+ if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
+ (!peek(p, '=') || (peek_n(p, '>', 1)))) {
+ result = tIDENTIFIER;
+ tokadd(p, c);
+ tokfix(p);
+ }
+ else {
+ pushback(p, c);
+ }
+ }
+ if (result == 0 && isupper((int)tok(p)[0])) {
+ result = tCONSTANT;
+ }
+ else {
+ result = tIDENTIFIER;
+ }
}
if (IS_LABEL_POSSIBLE()) {
- if (IS_LABEL_SUFFIX(0)) {
- p->lstate = EXPR_BEG;
- nextc(p);
- tokfix(p);
- yylval.id = intern(tok(p));
- return tLABEL;
- }
+ if (IS_LABEL_SUFFIX(0)) {
+ p->lstate = EXPR_BEG;
+ nextc(p);
+ tokfix(p);
+ yylval.id = intern(tok(p));
+ return tLABEL;
+ }
}
if (p->lstate != EXPR_DOT) {
- const struct kwtable *kw;
-
- /* See if it is a reserved word. */
- kw = mrb_reserved_word(tok(p), toklen(p));
- if (kw) {
- enum mrb_lex_state_enum state = p->lstate;
- p->lstate = kw->state;
- if (state == EXPR_FNAME) {
- yylval.id = intern(kw->name);
- return kw->id[0];
- }
- if (p->lstate == EXPR_BEG) {
- p->cmd_start = TRUE;
- }
- if (kw->id[0] == keyword_do) {
- if (p->lpar_beg && p->lpar_beg == p->paren_nest) {
- p->lpar_beg = 0;
- p->paren_nest--;
- return keyword_do_LAMBDA;
- }
- if (COND_P()) return keyword_do_cond;
- if (CMDARG_P() && state != EXPR_CMDARG)
- return keyword_do_block;
- if (state == EXPR_ENDARG || state == EXPR_BEG)
- return keyword_do_block;
- return keyword_do;
- }
- if (state == EXPR_BEG || state == EXPR_VALUE)
- return kw->id[0];
- else {
- if (kw->id[0] != kw->id[1])
- p->lstate = EXPR_BEG;
- return kw->id[1];
- }
- }
+ const struct kwtable *kw;
+
+ /* See if it is a reserved word. */
+ kw = mrb_reserved_word(tok(p), toklen(p));
+ if (kw) {
+ enum mrb_lex_state_enum state = p->lstate;
+ p->lstate = kw->state;
+ if (state == EXPR_FNAME) {
+ yylval.id = intern(kw->name);
+ return kw->id[0];
+ }
+ if (p->lstate == EXPR_BEG) {
+ p->cmd_start = TRUE;
+ }
+ if (kw->id[0] == keyword_do) {
+ if (p->lpar_beg && p->lpar_beg == p->paren_nest) {
+ p->lpar_beg = 0;
+ p->paren_nest--;
+ return keyword_do_LAMBDA;
+ }
+ if (COND_P()) return keyword_do_cond;
+ if (CMDARG_P() && state != EXPR_CMDARG)
+ return keyword_do_block;
+ if (state == EXPR_ENDARG || state == EXPR_BEG)
+ return keyword_do_block;
+ return keyword_do;
+ }
+ if (state == EXPR_BEG || state == EXPR_VALUE)
+ return kw->id[0];
+ else {
+ if (kw->id[0] != kw->id[1])
+ p->lstate = EXPR_BEG;
+ return kw->id[1];
+ }
+ }
}
- if (IS_BEG() ||
- p->lstate == EXPR_DOT ||
- IS_ARG()) {
- if (cmd_state) {
- p->lstate = EXPR_CMDARG;
- }
- else {
- p->lstate = EXPR_ARG;
- }
+ if (IS_BEG() || p->lstate == EXPR_DOT || IS_ARG()) {
+ if (cmd_state) {
+ p->lstate = EXPR_CMDARG;
+ }
+ else {
+ p->lstate = EXPR_ARG;
+ }
}
else if (p->lstate == EXPR_FNAME) {
- p->lstate = EXPR_ENDFN;
+ p->lstate = EXPR_ENDFN;
}
else {
- p->lstate = EXPR_END;
+ p->lstate = EXPR_END;
}
}
{
@@ -4729,7 +4951,7 @@ parser_yylex(parser_state *p)
yylval.id = ident;
#if 0
if (last_state != EXPR_DOT && islower(tok(p)[0]) && lvar_defined(ident)) {
- p->lstate = EXPR_END;
+ p->lstate = EXPR_END;
}
#endif
}
@@ -4740,12 +4962,12 @@ parser_yylex(parser_state *p)
static int
yylex(void *lval, parser_state *p)
{
- int t;
+ int t;
- p->ylval = lval;
- t = parser_yylex(p);
+ p->ylval = lval;
+ t = parser_yylex(p);
- return t;
+ return t;
}
static void
@@ -4844,6 +5066,8 @@ mrb_parser_new(mrb_state *mrb)
yydebug = 1;
#endif
+ p->heredocs = p->parsing_heredoc = NULL;
+
return p;
}
@@ -4930,7 +5154,7 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
char buf[256];
n = snprintf(buf, sizeof(buf), "line %d: %s\n",
- p->error_buffer[0].lineno, p->error_buffer[0].message);
+ p->error_buffer[0].lineno, p->error_buffer[0].message);
mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n));
mrb_parser_free(p);
return mrb_undef_value();
@@ -5047,23 +5271,23 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
dump_prefix(offset+1);
printf("rescue:\n");
while (n2) {
- node *n3 = n2->car;
- if (n3->car) {
- dump_prefix(offset+2);
- printf("handle classes:\n");
- dump_recur(mrb, n3->car, offset+3);
- }
- if (n3->cdr->car) {
- dump_prefix(offset+2);
- printf("exc_var:\n");
- parser_dump(mrb, n3->cdr->car, offset+3);
- }
- if (n3->cdr->cdr->car) {
- dump_prefix(offset+2);
- printf("rescue body:\n");
- parser_dump(mrb, n3->cdr->cdr->car, offset+3);
- }
- n2 = n2->cdr;
+ node *n3 = n2->car;
+ if (n3->car) {
+ dump_prefix(offset+2);
+ printf("handle classes:\n");
+ dump_recur(mrb, n3->car, offset+3);
+ }
+ if (n3->cdr->car) {
+ dump_prefix(offset+2);
+ printf("exc_var:\n");
+ parser_dump(mrb, n3->cdr->car, offset+3);
+ }
+ if (n3->cdr->cdr->car) {
+ dump_prefix(offset+2);
+ printf("rescue body:\n");
+ parser_dump(mrb, n3->cdr->cdr->car, offset+3);
+ }
+ n2 = n2->cdr;
}
}
tree = tree->cdr;
@@ -5096,40 +5320,40 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n = tree->car;
if (n->car) {
- dump_prefix(offset+1);
- printf("mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("optional args:\n");
- {
- node *n2 = n->car;
-
- while (n2) {
- dump_prefix(offset+2);
- printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
- parser_dump(mrb, n2->car->cdr, 0);
- n2 = n2->cdr;
- }
- }
+ dump_prefix(offset+1);
+ printf("optional args:\n");
+ {
+ node *n2 = n->car;
+
+ while (n2) {
+ dump_prefix(offset+2);
+ printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
+ parser_dump(mrb, n2->car->cdr, 0);
+ n2 = n2->cdr;
+ }
+ }
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+ dump_prefix(offset+1);
+ printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("post mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("post mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n) {
- dump_prefix(offset+1);
- printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
+ dump_prefix(offset+1);
+ printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
}
}
dump_prefix(offset+1);
@@ -5209,25 +5433,25 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n2 = tree->car;
if (n2->car) {
- dump_prefix(offset+2);
- printf("pre:\n");
- dump_recur(mrb, n2->car, offset+3);
+ dump_prefix(offset+2);
+ printf("pre:\n");
+ dump_recur(mrb, n2->car, offset+3);
}
n2 = n2->cdr;
if (n2) {
- if (n2->car) {
- dump_prefix(offset+2);
- printf("rest:\n");
- parser_dump(mrb, n2->car, offset+3);
- }
- n2 = n2->cdr;
- if (n2) {
- if (n2->car) {
- dump_prefix(offset+2);
- printf("post:\n");
- dump_recur(mrb, n2->car, offset+3);
- }
- }
+ if (n2->car) {
+ dump_prefix(offset+2);
+ printf("rest:\n");
+ parser_dump(mrb, n2->car, offset+3);
+ }
+ n2 = n2->cdr;
+ if (n2) {
+ if (n2->car) {
+ dump_prefix(offset+2);
+ printf("post:\n");
+ dump_recur(mrb, n2->car, offset+3);
+ }
+ }
}
}
tree = tree->cdr;
@@ -5246,17 +5470,17 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n2 = tree->car;
if (n2 && (n2->car || n2->cdr)) {
- dump_prefix(offset+1);
- printf("local variables:\n");
- dump_prefix(offset+2);
- while (n2) {
- if (n2->car) {
- if (n2 != tree->car) printf(", ");
- printf("%s", mrb_sym2name(mrb, sym(n2->car)));
- }
- n2 = n2->cdr;
- }
- printf("\n");
+ dump_prefix(offset+1);
+ printf("local variables:\n");
+ dump_prefix(offset+2);
+ while (n2) {
+ if (n2->car) {
+ if (n2 != tree->car) printf(", ");
+ printf("%s", mrb_sym2name(mrb, sym(n2->car)));
+ }
+ n2 = n2->cdr;
+ }
+ printf("\n");
}
}
tree = tree->cdr;
@@ -5269,17 +5493,17 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
parser_dump(mrb, tree->car, offset+1);
dump_prefix(offset+1);
printf("method='%s' (%d)\n",
- mrb_sym2name(mrb, sym(tree->cdr->car)),
- (int)(intptr_t)tree->cdr->car);
+ mrb_sym2name(mrb, sym(tree->cdr->car)),
+ (int)(intptr_t)tree->cdr->car);
tree = tree->cdr->cdr->car;
if (tree) {
dump_prefix(offset+1);
printf("args:\n");
dump_recur(mrb, tree->car, offset+2);
if (tree->cdr) {
- dump_prefix(offset+1);
- printf("block:\n");
- parser_dump(mrb, tree->cdr, offset+2);
+ dump_prefix(offset+1);
+ printf("block:\n");
+ parser_dump(mrb, tree->cdr, offset+2);
}
}
break;
@@ -5350,31 +5574,31 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n2 = tree->car;
if (n2->car) {
- dump_prefix(offset+2);
- printf("pre:\n");
- dump_recur(mrb, n2->car, offset+3);
+ dump_prefix(offset+2);
+ printf("pre:\n");
+ dump_recur(mrb, n2->car, offset+3);
}
n2 = n2->cdr;
if (n2) {
- if (n2->car) {
- dump_prefix(offset+2);
- printf("rest:\n");
+ if (n2->car) {
+ dump_prefix(offset+2);
+ printf("rest:\n");
if (n2->car == (node*)-1) {
- dump_prefix(offset+2);
- printf("(empty)\n");
- }
+ dump_prefix(offset+2);
+ printf("(empty)\n");
+ }
else {
- parser_dump(mrb, n2->car, offset+3);
- }
- }
- n2 = n2->cdr;
- if (n2) {
- if (n2->car) {
- dump_prefix(offset+2);
- printf("post:\n");
- dump_recur(mrb, n2->car, offset+3);
- }
- }
+ parser_dump(mrb, n2->car, offset+3);
+ }
+ }
+ n2 = n2->cdr;
+ if (n2) {
+ if (n2->car) {
+ dump_prefix(offset+2);
+ printf("post:\n");
+ dump_recur(mrb, n2->car, offset+3);
+ }
+ }
}
}
dump_prefix(offset+1);
@@ -5401,9 +5625,9 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
printf("args:\n");
dump_recur(mrb, tree->car, offset+2);
if (tree->cdr) {
- dump_prefix(offset+1);
- printf("block:\n");
- parser_dump(mrb, tree->cdr, offset+2);
+ dump_prefix(offset+1);
+ printf("block:\n");
+ parser_dump(mrb, tree->cdr, offset+2);
}
}
break;
@@ -5544,8 +5768,8 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_ALIAS:
printf("NODE_ALIAS %s %s:\n",
- mrb_sym2name(mrb, sym(tree->car)),
- mrb_sym2name(mrb, sym(tree->cdr)));
+ mrb_sym2name(mrb, sym(tree->car)),
+ mrb_sym2name(mrb, sym(tree->cdr)));
break;
case NODE_UNDEF:
@@ -5622,17 +5846,17 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n2 = tree->car;
if (n2 && (n2->car || n2->cdr)) {
- dump_prefix(offset+1);
- printf("local variables:\n");
- dump_prefix(offset+2);
- while (n2) {
- if (n2->car) {
- if (n2 != tree->car) printf(", ");
- printf("%s", mrb_sym2name(mrb, sym(n2->car)));
- }
- n2 = n2->cdr;
- }
- printf("\n");
+ dump_prefix(offset+1);
+ printf("local variables:\n");
+ dump_prefix(offset+2);
+ while (n2) {
+ if (n2->car) {
+ if (n2 != tree->car) printf(", ");
+ printf("%s", mrb_sym2name(mrb, sym(n2->car)));
+ }
+ n2 = n2->cdr;
+ }
+ printf("\n");
}
}
tree = tree->cdr;
@@ -5640,40 +5864,40 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n = tree->car;
if (n->car) {
- dump_prefix(offset+1);
- printf("mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("optional args:\n");
- {
- node *n2 = n->car;
-
- while (n2) {
- dump_prefix(offset+2);
- printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
- parser_dump(mrb, n2->car->cdr, 0);
- n2 = n2->cdr;
- }
- }
+ dump_prefix(offset+1);
+ printf("optional args:\n");
+ {
+ node *n2 = n->car;
+
+ while (n2) {
+ dump_prefix(offset+2);
+ printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
+ parser_dump(mrb, n2->car->cdr, 0);
+ n2 = n2->cdr;
+ }
+ }
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+ dump_prefix(offset+1);
+ printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("post mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("post mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n) {
- dump_prefix(offset+1);
- printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
+ dump_prefix(offset+1);
+ printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
}
}
parser_dump(mrb, tree->cdr->car, offset+1);
@@ -5690,40 +5914,40 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n = tree->car;
if (n->car) {
- dump_prefix(offset+1);
- printf("mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("optional args:\n");
- {
- node *n2 = n->car;
-
- while (n2) {
- dump_prefix(offset+2);
- printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
- parser_dump(mrb, n2->car->cdr, 0);
- n2 = n2->cdr;
- }
- }
+ dump_prefix(offset+1);
+ printf("optional args:\n");
+ {
+ node *n2 = n->car;
+
+ while (n2) {
+ dump_prefix(offset+2);
+ printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
+ parser_dump(mrb, n2->car->cdr, 0);
+ n2 = n2->cdr;
+ }
+ }
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+ dump_prefix(offset+1);
+ printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("post mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("post mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n) {
- dump_prefix(offset+1);
- printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
+ dump_prefix(offset+1);
+ printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
}
}
tree = tree->cdr;
@@ -5735,6 +5959,11 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
parser_dump(mrb, tree, offset+1);
break;
+ case NODE_HEREDOC:
+ printf("NODE_HEREDOC:\n");
+ parser_dump(mrb, ((parser_heredoc_info*)tree)->doc, offset+1);
+ break;
+
default:
printf("node type: %d (0x%x)\n", (int)n, (int)n);
break;
diff --git a/src/range.c b/src/range.c
index aac1d830a..59bf445aa 100644
--- a/src/range.c
+++ b/src/range.c
@@ -16,8 +16,8 @@ static void
range_check(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value ans;
- int ta;
- int tb;
+ enum mrb_vtype ta;
+ enum mrb_vtype tb;
ta = mrb_type(a);
tb = mrb_type(b);
@@ -181,7 +181,7 @@ r_le(mrb_state *mrb, mrb_value a, mrb_value b)
/* output :a < b => -1, a = b => 0, a > b => +1 */
if (mrb_type(r) == MRB_TT_FIXNUM) {
- int c = mrb_fixnum(r);
+ mrb_int c = mrb_fixnum(r);
if (c == 0 || c == -1) return TRUE;
}
@@ -208,7 +208,7 @@ r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
/* output :a < b => -1, a = b => 0, a > b => +1 */
if (mrb_type(r) == MRB_TT_FIXNUM) {
- int c = mrb_fixnum(r);
+ mrb_int c = mrb_fixnum(r);
if (c == 0 || c == 1) return TRUE;
}
diff --git a/src/state.c b/src/state.c
index 53773ac89..1936b8aab 100644
--- a/src/state.c
+++ b/src/state.c
@@ -72,7 +72,7 @@ mrb_alloca_free(mrb_state *mrb)
}
mrb_state*
-mrb_open()
+mrb_open(void)
{
mrb_state *mrb = mrb_open_allocf(allocf, NULL);
@@ -110,6 +110,10 @@ mrb_close(mrb_state *mrb)
mrb_free(mrb, mrb);
}
+#ifndef MRB_IREP_ARRAY_INIT_SIZE
+# define MRB_IREP_ARRAY_INIT_SIZE (256u)
+#endif
+
mrb_irep*
mrb_add_irep(mrb_state *mrb)
{
@@ -117,7 +121,7 @@ mrb_add_irep(mrb_state *mrb)
mrb_irep *irep;
if (!mrb->irep) {
- int max = 256;
+ size_t max = MRB_IREP_ARRAY_INIT_SIZE;
if (mrb->irep_len > max) max = mrb->irep_len+1;
mrb->irep = (mrb_irep **)mrb_calloc(mrb, max, sizeof(mrb_irep*));
diff --git a/src/string.c b/src/string.c
index 28cf0ab9a..23da3baa6 100644
--- a/src/string.c
+++ b/src/string.c
@@ -2056,7 +2056,6 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
char *end;
char sign = 1;
int c;
- long len;
unsigned long val;
#undef ISDIGIT
@@ -2113,30 +2112,25 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
}
switch (base) {
case 2:
- len = 1;
if (str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {
str += 2;
}
break;
case 3:
- len = 2;
break;
case 8:
if (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {
str += 2;
}
case 4: case 5: case 6: case 7:
- len = 3;
break;
case 10:
if (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {
str += 2;
}
case 9: case 11: case 12: case 13: case 14: case 15:
- len = 4;
break;
case 16:
- len = 4;
if (str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {
str += 2;
}
@@ -2145,12 +2139,6 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
if (base < 2 || 36 < base) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %d", base);
}
- if (base <= 32) {
- len = 5;
- }
- else {
- len = 6;
- }
break;
} /* end of switch (base) { */
if (*str == '0') { /* squeeze preceeding 0s */
@@ -2171,7 +2159,6 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
if (badcheck) goto bad;
return mrb_fixnum_value(0);
}
- len *= strlen(str);
val = strtoul((char*)str, &end, base);
diff --git a/src/variable.c b/src/variable.c
index 5f657e3d7..d5331f844 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -753,7 +753,7 @@ mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
struct RClass *c = mrb->ci->proc->target_class;
if (!c) c = mrb->ci->target_class;
-
+
return mrb_mod_cv_get(mrb, c, sym);
}
diff --git a/test/t/literals.rb b/test/t/literals.rb
index c996af3f3..9a6d341d4 100644
--- a/test/t/literals.rb
+++ b/test/t/literals.rb
@@ -59,7 +59,74 @@ assert('Literals Strings Quoted Expanded', '8.7.6.3.5') do
e == 'abc' and f == 'ab/c' and g == 'abc'
end
-# Not Implemented ATM assert('Literals Strings Here documents', '8.7.6.3.6') do
+assert('Literals Strings Here documents', '8.7.6.3.6') do
+ a = <<AAA
+aaa
+AAA
+ b = <<b_b
+bbb
+b_b
+ c = [<<CCC1, <<"CCC2", <<'CCC3']
+c1
+CCC1
+c 2
+CCC2
+c 3
+CCC3
+
+ d = <<DDD
+d#{1+2}DDD
+d\t
+DDD\n
+DDD
+ e = <<'EEE'
+e#{1+2}EEE
+e\t
+EEE\n
+EEE
+ f = <<"FFF"
+F
+FF#{"f"}FFF
+F
+FFF
+
+ g = <<-GGG
+ ggg
+ GGG
+ h = <<-"HHH"
+ hhh
+ HHH
+ i = <<-'III'
+ iii
+ III
+ j = [<<-JJJ1 , <<-"JJJ2" , <<-'JJJ3' ]
+ j#{1}j
+ JJJ1
+ j#{2}j
+ JJJ2
+ j#{3}j
+ JJJ3
+
+ k = <<'KKK'.to_i
+123
+KKK
+
+ z = <<'ZZZ'
+ZZZ
+
+ a == "aaa\n" and
+ b == "bbb\n" and
+ c == ["c1\n", "c 2\n", "c 3\n"] and
+ d == "d3DDD\nd\t\nDDD\n\n" and
+ e == "e\#{1+2}EEE\ne\\t\nEEE\\n\n" and
+ f == "F\nFFfFFF\nF\n" and
+ g == " ggg\n" and
+ h == " hhh\n" and
+ i == " iii\n" and
+ j == [" j1j\n", " j2j\n", " j\#{3}j\n"] and
+ k == 123 and
+ z == ""
+end
# Not Implemented ATM assert('Literals Array', '8.7.6.4') do
diff --git a/tools/mirb/mirb.c b/tools/mirb/mirb.c
index 29685cf28..e20de629d 100644
--- a/tools/mirb/mirb.c
+++ b/tools/mirb/mirb.c
@@ -40,6 +40,13 @@ is_code_block_open(struct mrb_parser_state *parser)
/* check for unterminated string */
if (parser->sterm) return TRUE;
+ /* check for heredoc */
+ if (parser->heredoc_starts_nextline) return TRUE;
+ if (parser->heredoc_end_now) {
+ parser->heredoc_end_now = FALSE;
+ return FALSE;
+ }
+
/* check if parser error are available */
if (0 < parser->nerr) {
const char *unexpected_end = "syntax error, unexpected $end";