Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mruby
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
mruby
Commits
8161f0f6
Commit
8161f0f6
authored
May 18, 2013
by
Ryan Scott
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
008aec2b
c8c4dfe4
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
396 additions
and
172 deletions
+396
-172
build_config.rb
build_config.rb
+5
-0
include/mruby.h
include/mruby.h
+1
-0
include/mruby/compile.h
include/mruby/compile.h
+5
-0
mrbgems/mruby-array-ext/mrblib/array.rb
mrbgems/mruby-array-ext/mrblib/array.rb
+106
-0
mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
+2
-64
src/backtrace.c
src/backtrace.c
+73
-0
src/codegen.c
src/codegen.c
+7
-1
src/load.c
src/load.c
+0
-3
src/parse.y
src/parse.y
+25
-3
src/state.c
src/state.c
+1
-0
tasks/mrbgem_spec.rake
tasks/mrbgem_spec.rake
+1
-0
tasks/mruby_build_commands.rake
tasks/mruby_build_commands.rake
+8
-7
tools/mrbc/mrbc.c
tools/mrbc/mrbc.c
+162
-94
No files found.
build_config.rb
View file @
8161f0f6
...
...
@@ -25,6 +25,11 @@ MRuby::Build.new do |conf|
# cc.compile_options = "%{flags} -MMD -o %{outfile} -c %{infile}"
# end
# mrbc settings
# conf.mrbc do |mrbc|
# mrbc.compile_options = "-g -B%{funcname} -o-" # The -g option is required for line numbers
# end
# Linker settings
# conf.linker do |linker|
# linker.command = ENV['LD'] || 'gcc'
...
...
include/mruby.h
View file @
8161f0f6
...
...
@@ -301,6 +301,7 @@ void mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...);
void
mrb_name_error
(
mrb_state
*
mrb
,
mrb_sym
id
,
const
char
*
fmt
,
...);
void
mrb_warn
(
mrb_state
*
mrb
,
const
char
*
fmt
,
...);
void
mrb_bug
(
mrb_state
*
mrb
,
const
char
*
fmt
,
...);
void
mrb_print_backtrace
(
mrb_state
*
mrb
);
/* macros to get typical exception objects
note:
...
...
include/mruby/compile.h
View file @
8161f0f6
...
...
@@ -14,12 +14,15 @@ extern "C" {
#include "mruby.h"
#include <setjmp.h>
struct
mrb_parser_state
;
/* load context */
typedef
struct
mrbc_context
{
mrb_sym
*
syms
;
int
slen
;
char
*
filename
;
short
lineno
;
int
(
*
partial_hook
)(
struct
mrb_parser_state
*
);
void
*
partial_data
;
mrb_bool
capture_errors
:
1
;
mrb_bool
dump_result
:
1
;
mrb_bool
no_exec
:
1
;
...
...
@@ -28,6 +31,7 @@ typedef struct 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
);
void
mrbc_partial_hook
(
mrb_state
*
mrb
,
mrbc_context
*
c
,
int
(
*
partial_hook
)(
struct
mrb_parser_state
*
),
void
*
data
);
/* AST node structure */
typedef
struct
mrb_ast_node
{
...
...
@@ -104,6 +108,7 @@ struct mrb_parser_state {
#ifdef ENABLE_STDIO
FILE
*
f
;
#endif
mrbc_context
*
cxt
;
char
*
filename
;
int
lineno
;
int
column
;
...
...
mrbgems/mruby-array-ext/mrblib/array.rb
View file @
8161f0f6
class
Array
##
# call-seq:
# ary.uniq! -> ary or nil
#
# Removes duplicate elements from +self+.
# Returns <code>nil</code> if no changes are made (that is, no
# duplicates are found).
#
# a = [ "a", "a", "b", "b", "c" ]
# a.uniq! #=> ["a", "b", "c"]
# b = [ "a", "b", "c" ]
# b.uniq! #=> nil
#
def
uniq!
ary
=
self
.
dup
result
=
[]
...
...
@@ -13,12 +26,32 @@ class Array
end
end
##
# call-seq:
# ary.uniq -> new_ary
#
# Returns a new array by removing duplicate values in +self+.
#
# a = [ "a", "a", "b", "b", "c" ]
# a.uniq #=> ["a", "b", "c"]
#
def
uniq
ary
=
self
.
dup
ary
.
uniq!
ary
end
##
# call-seq:
# ary - other_ary -> new_ary
#
# Array Difference---Returns a new array that is a copy of
# the original array, removing any items that also appear in
# <i>other_ary</i>. (If you need set-like behavior, see the
# library class Set.)
#
# [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
#
def
-
(
elem
)
raise
TypeError
,
"can't convert
#{
elem
.
class
}
into Array"
unless
elem
.
class
==
Array
...
...
@@ -29,6 +62,16 @@ class Array
array
end
##
# call-seq:
# ary | other_ary -> new_ary
#
# Set Union---Returns a new array by joining this array with
# <i>other_ary</i>, removing duplicates.
#
# [ "a", "b", "c" ] | [ "c", "d", "a" ]
# #=> [ "a", "b", "c", "d" ]
#
def
|
(
elem
)
raise
TypeError
,
"can't convert
#{
elem
.
class
}
into Array"
unless
elem
.
class
==
Array
...
...
@@ -36,6 +79,15 @@ class Array
ary
.
uniq!
or
ary
end
##
# call-seq:
# ary & other_ary -> new_ary
#
# Set Intersection---Returns a new array
# containing elements common to the two arrays, with no duplicates.
#
# [ 1, 1, 3, 5 ] & [ 1, 2, 3 ] #=> [ 1, 3 ]
#
def
&
(
elem
)
raise
TypeError
,
"can't convert
#{
elem
.
class
}
into Array"
unless
elem
.
class
==
Array
...
...
@@ -51,6 +103,23 @@ class Array
array
end
##
# call-seq:
# ary.flatten -> new_ary
# ary.flatten(level) -> new_ary
#
# Returns a new array that is a one-dimensional flattening of this
# array (recursively). That is, for every element that is an array,
# extract its elements into the new array. If the optional
# <i>level</i> argument determines the level of recursion to flatten.
#
# s = [ 1, 2, 3 ] #=> [1, 2, 3]
# t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
# a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
# a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# a = [ 1, 2, [3, [4, 5] ] ]
# a.flatten(1) #=> [1, 2, 3, [4, 5]]
#
def
flatten
(
depth
=
nil
)
ar
=
[]
self
.
each
do
|
e
|
...
...
@@ -63,6 +132,23 @@ class Array
ar
end
##
# call-seq:
# ary.flatten! -> ary or nil
# ary.flatten!(level) -> array or nil
#
# Flattens +self+ in place.
# Returns <code>nil</code> if no modifications were made (i.e.,
# <i>ary</i> contains no subarrays.) If the optional <i>level</i>
# argument determines the level of recursion to flatten.
#
# a = [ 1, 2, [3, [4, 5] ] ]
# a.flatten! #=> [1, 2, 3, 4, 5]
# a.flatten! #=> nil
# a #=> [1, 2, 3, 4, 5]
# a = [ 1, 2, [3, [4, 5] ] ]
# a.flatten!(1) #=> [1, 2, 3, [4, 5]]
#
def
flatten!
(
depth
=
nil
)
modified
=
false
ar
=
[]
...
...
@@ -81,12 +167,32 @@ class Array
end
end
##
# call-seq:
# ary.compact -> new_ary
#
# Returns a copy of +self+ with all +nil+ elements removed.
#
# [ "a", nil, "b", nil, "c", nil ].compact
# #=> [ "a", "b", "c" ]
#
def
compact
result
=
self
.
dup
result
.
compact!
result
end
##
# call-seq:
# ary.compact! -> ary or nil
#
# Removes +nil+ elements from the array.
# Returns +nil+ if no changes were made, otherwise returns
# <i>ary</i>.
#
# [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ]
# [ "a", "b", "c" ].compact! #=> nil
#
def
compact!
result
=
self
.
select
{
|
e
|
e
!=
nil
}
if
result
.
size
==
self
.
size
...
...
mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
View file @
8161f0f6
...
...
@@ -162,68 +162,6 @@ cleanup(mrb_state *mrb, struct _args *args)
mrb_close
(
mrb
);
}
static
void
showcallinfo
(
mrb_state
*
mrb
)
{
mrb_callinfo
*
ci
;
mrb_int
ciidx
;
const
char
*
filename
,
*
method
,
*
sep
;
int
i
,
line
;
printf
(
"trace:
\n
"
);
ciidx
=
mrb_fixnum
(
mrb_obj_iv_get
(
mrb
,
mrb
->
exc
,
mrb_intern
(
mrb
,
"ciidx"
)));
if
(
ciidx
>=
mrb
->
ciend
-
mrb
->
cibase
)
ciidx
=
10
;
/* ciidx is broken... */
for
(
i
=
ciidx
;
i
>=
0
;
i
--
)
{
ci
=
&
mrb
->
cibase
[
i
];
filename
=
"(unknown)"
;
line
=
-
1
;
if
(
MRB_PROC_CFUNC_P
(
ci
->
proc
))
{
continue
;
}
else
{
mrb_irep
*
irep
=
ci
->
proc
->
body
.
irep
;
if
(
irep
->
filename
!=
NULL
)
filename
=
irep
->
filename
;
if
(
irep
->
lines
!=
NULL
)
{
mrb_code
*
pc
;
if
(
i
+
1
<=
ciidx
)
{
pc
=
mrb
->
cibase
[
i
+
1
].
pc
;
}
else
{
pc
=
(
mrb_code
*
)
mrb_voidp
(
mrb_obj_iv_get
(
mrb
,
mrb
->
exc
,
mrb_intern
(
mrb
,
"lastpc"
)));
}
if
(
irep
->
iseq
<=
pc
&&
pc
<
irep
->
iseq
+
irep
->
ilen
)
{
line
=
irep
->
lines
[
pc
-
irep
->
iseq
-
1
];
}
}
}
if
(
line
==
-
1
)
continue
;
if
(
ci
->
target_class
==
ci
->
proc
->
target_class
)
sep
=
"."
;
else
sep
=
"#"
;
method
=
mrb_sym2name
(
mrb
,
ci
->
mid
);
if
(
method
)
{
const
char
*
cn
=
mrb_class_name
(
mrb
,
ci
->
proc
->
target_class
);
if
(
cn
)
{
printf
(
"
\t
[%d] %s:%d:in %s%s%s
\n
"
,
i
,
filename
,
line
,
cn
,
sep
,
method
);
}
else
{
printf
(
"
\t
[%d] %s:%d:in %s
\n
"
,
i
,
filename
,
line
,
method
);
}
}
else
{
printf
(
"
\t
[%d] %s:%d
\n
"
,
i
,
filename
,
line
);
}
}
}
int
main
(
int
argc
,
char
**
argv
)
{
...
...
@@ -260,7 +198,7 @@ main(int argc, char **argv)
mrb_run
(
mrb
,
mrb_proc_new
(
mrb
,
mrb
->
irep
[
n
]),
mrb_top_self
(
mrb
));
n
=
0
;
if
(
mrb
->
exc
)
{
showcallinfo
(
mrb
);
mrb_print_backtrace
(
mrb
);
p
(
mrb
,
mrb_obj_value
(
mrb
->
exc
));
n
=
-
1
;
}
...
...
@@ -292,7 +230,7 @@ main(int argc, char **argv)
mrbc_context_free
(
mrb
,
c
);
if
(
mrb
->
exc
)
{
if
(
!
mrb_undef_p
(
v
))
{
showcallinfo
(
mrb
);
mrb_print_backtrace
(
mrb
);
p
(
mrb
,
mrb_obj_value
(
mrb
->
exc
));
}
n
=
-
1
;
...
...
src/backtrace.c
0 → 100644
View file @
8161f0f6
/*
** backtrace.c -
**
** See Copyright Notice in mruby.h
*/
#include "mruby.h"
#include "mruby/variable.h"
#include "mruby/proc.h"
void
mrb_print_backtrace
(
mrb_state
*
mrb
)
{
#ifdef ENABLE_STDIO
mrb_callinfo
*
ci
;
mrb_int
ciidx
;
const
char
*
filename
,
*
method
,
*
sep
;
int
i
,
line
;
printf
(
"trace:
\n
"
);
ciidx
=
mrb_fixnum
(
mrb_obj_iv_get
(
mrb
,
mrb
->
exc
,
mrb_intern
(
mrb
,
"ciidx"
)));
if
(
ciidx
>=
mrb
->
ciend
-
mrb
->
cibase
)
ciidx
=
10
;
/* ciidx is broken... */
for
(
i
=
ciidx
;
i
>=
0
;
i
--
)
{
ci
=
&
mrb
->
cibase
[
i
];
filename
=
"(unknown)"
;
line
=
-
1
;
if
(
MRB_PROC_CFUNC_P
(
ci
->
proc
))
{
continue
;
}
else
{
mrb_irep
*
irep
=
ci
->
proc
->
body
.
irep
;
if
(
irep
->
filename
!=
NULL
)
filename
=
irep
->
filename
;
if
(
irep
->
lines
!=
NULL
)
{
mrb_code
*
pc
;
if
(
i
+
1
<=
ciidx
)
{
pc
=
mrb
->
cibase
[
i
+
1
].
pc
;
}
else
{
pc
=
(
mrb_code
*
)
mrb_voidp
(
mrb_obj_iv_get
(
mrb
,
mrb
->
exc
,
mrb_intern
(
mrb
,
"lastpc"
)));
}
if
(
irep
->
iseq
<=
pc
&&
pc
<
irep
->
iseq
+
irep
->
ilen
)
{
line
=
irep
->
lines
[
pc
-
irep
->
iseq
-
1
];
}
}
}
if
(
line
==
-
1
)
continue
;
if
(
ci
->
target_class
==
ci
->
proc
->
target_class
)
sep
=
"."
;
else
sep
=
"#"
;
method
=
mrb_sym2name
(
mrb
,
ci
->
mid
);
if
(
method
)
{
const
char
*
cn
=
mrb_class_name
(
mrb
,
ci
->
proc
->
target_class
);
if
(
cn
)
{
printf
(
"
\t
[%d] %s:%d:in %s%s%s
\n
"
,
i
,
filename
,
line
,
cn
,
sep
,
method
);
}
else
{
printf
(
"
\t
[%d] %s:%d:in %s
\n
"
,
i
,
filename
,
line
,
method
);
}
}
else
{
printf
(
"
\t
[%d] %s:%d
\n
"
,
i
,
filename
,
line
);
}
}
#endif
}
src/codegen.c
View file @
8161f0f6
...
...
@@ -2403,6 +2403,8 @@ scope_finish(codegen_scope *s)
{
mrb_state
*
mrb
=
s
->
mrb
;
mrb_irep
*
irep
=
s
->
irep
;
size_t
fname_len
;
char
*
fname
;
irep
->
flags
=
0
;
if
(
s
->
iseq
)
{
...
...
@@ -2418,7 +2420,11 @@ scope_finish(codegen_scope *s)
irep
->
pool
=
(
mrb_value
*
)
codegen_realloc
(
s
,
irep
->
pool
,
sizeof
(
mrb_value
)
*
irep
->
plen
);
irep
->
syms
=
(
mrb_sym
*
)
codegen_realloc
(
s
,
irep
->
syms
,
sizeof
(
mrb_sym
)
*
irep
->
slen
);
if
(
s
->
filename
)
{
irep
->
filename
=
s
->
filename
;
fname_len
=
strlen
(
s
->
filename
);
fname
=
codegen_malloc
(
s
,
fname_len
+
1
);
memcpy
(
fname
,
s
->
filename
,
fname_len
);
fname
[
fname_len
]
=
'\0'
;
irep
->
filename
=
fname
;
}
irep
->
nlocals
=
s
->
nlocals
;
...
...
src/load.c
View file @
8161f0f6
...
...
@@ -267,9 +267,6 @@ read_rite_lineno_record(mrb_state *mrb, const uint8_t *bin, size_t irepno, uint3
mrb
->
irep
[
irepno
]
->
lines
=
lines
;
error_exit:
if
(
fname
)
{
mrb_free
(
mrb
,
fname
);
}
return
ret
;
}
...
...
src/parse.y
View file @
8161f0f6
...
...
@@ -3232,14 +3232,14 @@ nextc(parser_state *p)
else {
#ifdef ENABLE_STDIO
if (p->f) {
if (feof(p->f))
return -1
;
if (feof(p->f))
goto end_retry
;
c = fgetc(p->f);
if (c == EOF)
return -1
;
if (c == EOF)
goto end_retry
;
}
else
#endif
if (!p->s || p->s >= p->send) {
return -1
;
goto end_retry
;
}
else {
c = (unsigned char)*p->s++;
...
...
@@ -3247,6 +3247,18 @@ nextc(parser_state *p)
}
p->column++;
return c;
end_retry:
if (!p->cxt) return -1;
else {
mrbc_context *cxt = p->cxt;
if (cxt->partial_hook(p) < 0) return -1;
p->cxt = NULL;
c = nextc(p);
p->cxt = cxt;
return c;
}
}
static void
...
...
@@ -5023,6 +5035,9 @@ parser_init_cxt(parser_state *p, mrbc_context *cxt)
}
}
p->capture_errors = cxt->capture_errors;
if (cxt->partial_hook) {
p->cxt = cxt;
}
}
static void
...
...
@@ -5147,6 +5162,13 @@ mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s)
return c->filename;
}
void
mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*func)(struct mrb_parser_state*), void *data)
{
c->partial_hook = func;
c->partial_data = data;
}
#ifdef ENABLE_STDIO
parser_state*
mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c)
...
...
src/state.c
View file @
8161f0f6
...
...
@@ -101,6 +101,7 @@ mrb_irep_free(mrb_state *mrb, struct mrb_irep *irep)
mrb_free
(
mrb
,
irep
->
iseq
);
mrb_free
(
mrb
,
irep
->
pool
);
mrb_free
(
mrb
,
irep
->
syms
);
mrb_free
(
mrb
,
(
void
*
)
irep
->
filename
);
mrb_free
(
mrb
,
irep
->
lines
);
mrb_free
(
mrb
,
irep
);
}
...
...
tasks/mrbgem_spec.rake
View file @
8161f0f6
...
...
@@ -136,6 +136,7 @@ module MRuby
unless
rbfiles
.
empty?
f
.
puts
%Q[ mrb_load_irep(mrb, gem_mrblib_irep_
#{
funcname
}
);]
f
.
puts
%Q[ if (mrb->exc) {]
f
.
puts
%Q[ mrb_print_backtrace(mrb);]
f
.
puts
%Q[ mrb_p(mrb, mrb_obj_value(mrb->exc));]
f
.
puts
%Q[ exit(EXIT_FAILURE);]
f
.
puts
%Q[ }]
...
...
tasks/mruby_build_commands.rake
View file @
8161f0f6
...
...
@@ -236,20 +236,21 @@ module MRuby
end
class
Command::Mrbc
<
Command
attr_accessor
:compile_options
def
initialize
(
build
)
super
@command
=
nil
@compile_options
=
"-B%{funcname} -o-
-
"
@compile_options
=
"-B%{funcname} -o-"
end
def
run
(
out
,
infiles
,
funcname
)
@command
||=
@build
.
mrbcfile
IO
.
popen
(
"
#{
filename
@command
}
#{
@compile_options
%
{
:funcname
=>
funcname
}
}"
,
'r+'
)
do
|
io
|
[
infiles
].
flatten
.
each
do
|
f
|
infiles
=
[
infiles
].
flatten
infiles
.
each
do
|
f
|
_pp
"MRBC"
,
f
.
relative_path
,
nil
,
:indent
=>
2
io
.
write
IO
.
read
(
f
)
end
io
.
close_write
IO
.
popen
(
"
#{
filename
@command
}
#{
@compile_options
%
{
:funcname
=>
funcname
}
}
#{
infiles
.
join
(
' '
)
}
"
,
'r+'
)
do
|
io
|
out
.
puts
io
.
read
end
end
...
...
tools/mrbc/mrbc.c
View file @
8161f0f6
...
...
@@ -14,12 +14,13 @@ void mrb_show_copyright(mrb_state *);
void
parser_dump
(
mrb_state
*
,
struct
mrb_ast_node
*
,
int
);
void
codedump_all
(
mrb_state
*
,
int
);
struct
_args
{
FILE
*
rfp
;
FILE
*
wfp
;
char
*
filename
;
char
*
initname
;
char
*
ext
;
struct
mrbc_args
{
int
argc
;
char
**
argv
;
int
idx
;
const
char
*
prog
;
const
char
*
outfile
;
const
char
*
initname
;
mrb_bool
check_syntax
:
1
;
mrb_bool
verbose
:
1
;
mrb_bool
debug_info
:
1
;
...
...
@@ -65,42 +66,45 @@ get_outfilename(mrb_state *mrb, char *infile, char *ext)
}
static
int
parse_args
(
mrb_state
*
mrb
,
int
argc
,
char
**
argv
,
struct
_args
*
args
)
parse_args
(
mrb_state
*
mrb
,
int
argc
,
char
**
argv
,
struct
mrbc
_args
*
args
)
{
char
*
infile
=
NULL
;
char
*
outfile
=
NULL
;
char
**
origargv
=
argv
;
int
result
=
EXIT_SUCCESS
;
static
const
struct
_args
args_zero
=
{
0
};
static
const
struct
mrbc_args
args_zero
=
{
0
};
int
i
;
*
args
=
args_zero
;
args
->
ext
=
RITEBIN_EXT
;
args
->
argc
=
argc
;
args
->
argv
=
argv
;
args
->
prog
=
argv
[
0
];
for
(
argc
--
,
argv
++
;
argc
>
0
;
argc
--
,
argv
++
)
{
if
(
**
argv
==
'-'
)
{
if
(
strlen
(
*
argv
)
==
1
)
{
args
->
filename
=
infile
=
"-"
;
args
->
rfp
=
stdin
;
break
;
}
switch
((
*
argv
)[
1
])
{
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
if
(
argv
[
i
][
0
]
==
'-'
)
{
switch
((
argv
[
i
])[
1
])
{
case
'o'
:
if
(
outfile
)
{
printf
(
"%s: An output file is already specified. (%s)
\n
"
,
*
origargv
,
outfile
);
result
=
EXIT_FAILURE
;
goto
exit
;
if
(
args
->
outfile
)
{
fprintf
(
stderr
,
"%s: an output file is already specified. (%s)
\n
"
,
args
->
prog
,
outfile
);
return
-
1
;
}
if
(
argv
[
i
][
2
]
==
'\0'
&&
argv
[
i
+
1
])
{
i
++
;
args
->
outfile
=
get_outfilename
(
mrb
,
argv
[
i
],
""
);
}
else
{
args
->
outfile
=
get_outfilename
(
mrb
,
argv
[
i
]
+
2
,
""
);
}
outfile
=
get_outfilename
(
mrb
,
(
*
argv
)
+
2
,
""
);
break
;
case
'B'
:
args
->
ext
=
C_EXT
;
args
->
initname
=
(
*
argv
)
+
2
;
if
(
argv
[
i
][
2
]
==
'\0'
&&
argv
[
i
+
1
])
{
i
++
;
args
->
initname
=
argv
[
i
];
}
else
{
args
->
initname
=
argv
[
i
]
+
2
;
}
if
(
*
args
->
initname
==
'\0'
)
{
printf
(
"%s: Function name is not specified.
\n
"
,
*
origargv
);
result
=
EXIT_FAILURE
;
goto
exit
;
fprintf
(
stderr
,
"%s: function name is not specified.
\n
"
,
args
->
prog
);
return
-
1
;
}
break
;
case
'c'
:
...
...
@@ -114,79 +118,124 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
args
->
debug_info
=
1
;
break
;
case
'-'
:
if
(
strcmp
((
*
argv
)
+
2
,
"version"
)
==
0
)
{
if
(
argv
[
i
][
1
]
==
'\n'
)
{
return
i
;
}
if
(
strcmp
(
argv
[
i
]
+
2
,
"version"
)
==
0
)
{
mrb_show_version
(
mrb
);
exit
(
EXIT_SUCCESS
);
}
else
if
(
strcmp
(
(
*
argv
)
+
2
,
"verbose"
)
==
0
)
{
else
if
(
strcmp
(
argv
[
i
]
+
2
,
"verbose"
)
==
0
)
{
args
->
verbose
=
1
;
break
;
}
else
if
(
strcmp
(
(
*
argv
)
+
2
,
"copyright"
)
==
0
)
{
else
if
(
strcmp
(
argv
[
i
]
+
2
,
"copyright"
)
==
0
)
{
mrb_show_copyright
(
mrb
);
exit
(
EXIT_SUCCESS
);
}
result
=
EXIT_FAILURE
;
goto
exit
;
return
-
1
;
default:
break
;
}
return
i
;
}
else
if
(
args
->
rfp
==
NULL
)
{
args
->
filename
=
infile
=
*
argv
;
if
((
args
->
rfp
=
fopen
(
infile
,
"r"
))
==
NULL
)
{
printf
(
"%s: Cannot open program file. (%s)
\n
"
,
*
origargv
,
infile
);
goto
exit
;
}
else
{
break
;
}
}
return
i
;
}
if
(
infile
==
NULL
)
{
result
=
EXIT_FAILURE
;
goto
exit
;
}
if
(
!
args
->
check_syntax
)
{
if
(
outfile
==
NULL
)
{
if
(
strcmp
(
"-"
,
infile
)
==
0
)
{
outfile
=
infile
;
}
else
{
outfile
=
get_outfilename
(
mrb
,
infile
,
args
->
ext
);
static
void
cleanup
(
mrb_state
*
mrb
,
struct
mrbc_args
*
args
)
{
if
(
args
->
outfile
)
mrb_free
(
mrb
,
(
void
*
)
args
->
outfile
);
mrb_close
(
mrb
);
}
static
int
partial_hook
(
struct
mrb_parser_state
*
p
)
{
mrbc_context
*
c
=
p
->
cxt
;
struct
mrbc_args
*
args
=
(
struct
mrbc_args
*
)
c
->
partial_data
;
if
(
p
->
f
)
fclose
(
p
->
f
);
if
(
args
->
idx
>=
args
->
argc
)
{
p
->
f
=
NULL
;
return
-
1
;
}
mrbc_filename
(
p
->
mrb
,
c
,
args
->
argv
[
args
->
idx
++
]);
p
->
f
=
fopen
(
c
->
filename
,
"r"
);
if
(
p
->
f
==
NULL
)
{
fprintf
(
stderr
,
"%s: cannot open program file. (%s)
\n
"
,
args
->
prog
,
c
->
filename
);
return
-
1
;
}
if
(
strcmp
(
"-"
,
outfile
)
==
0
)
{
args
->
wfp
=
stdout
;
p
->
filename
=
c
->
filename
;
p
->
lineno
=
1
;
return
0
;
}
static
int
load_file
(
mrb_state
*
mrb
,
struct
mrbc_args
*
args
)
{
mrbc_context
*
c
;
mrb_value
result
;
char
*
input
=
args
->
argv
[
args
->
idx
];
FILE
*
infile
;
c
=
mrbc_context_new
(
mrb
);
if
(
args
->
verbose
)
c
->
dump_result
=
1
;
c
->
no_exec
=
1
;
if
(
input
[
0
]
==
'-'
&&
input
[
1
]
==
'\0'
)
{
infile
=
stdin
;
}
else
if
((
args
->
wfp
=
fopen
(
outfile
,
"wb"
))
==
NULL
)
{
printf
(
"%s: Cannot open output file. (%s)
\n
"
,
*
origargv
,
outfile
);
result
=
EXIT_FAILURE
;
goto
exit
;
else
if
((
infile
=
fopen
(
input
,
"r"
))
==
NULL
)
{
fprintf
(
stderr
,
"%s: cannot open program file. (%s)
\n
"
,
args
->
prog
,
input
);
return
EXIT_FAILURE
;
}
mrbc_filename
(
mrb
,
c
,
input
);
args
->
idx
++
;
if
(
args
->
idx
<
args
->
argc
)
{
mrbc_partial_hook
(
mrb
,
c
,
partial_hook
,
(
void
*
)
args
);
}
exit:
if
(
outfile
&&
infile
!=
outfile
)
mrb_free
(
mrb
,
outfile
);
return
result
;
result
=
mrb_load_file_cxt
(
mrb
,
infile
,
c
);
if
(
mrb_undef_p
(
result
)
||
mrb_fixnum
(
result
)
<
0
)
{
mrbc_context_free
(
mrb
,
c
);
return
EXIT_FAILURE
;
}
mrbc_context_free
(
mrb
,
c
);
return
EXIT_SUCCESS
;
}
static
void
cleanup
(
mrb_state
*
mrb
,
struct
_args
*
args
)
static
int
dump_file
(
mrb_state
*
mrb
,
FILE
*
wfp
,
const
char
*
outfile
,
struct
mrbc
_args
*
args
)
{
if
(
args
->
rfp
)
fclose
(
args
->
rfp
);
if
(
args
->
wfp
)
fclose
(
args
->
wfp
);
mrb_close
(
mrb
);
int
n
=
MRB_DUMP_OK
;
if
(
args
->
initname
)
{
n
=
mrb_dump_irep_cfunc
(
mrb
,
0
,
args
->
debug_info
,
wfp
,
args
->
initname
);
if
(
n
==
MRB_DUMP_INVALID_ARGUMENT
)
{
fprintf
(
stderr
,
"%s: invalid C language symbol name
\n
"
,
args
->
initname
);
}
}
else
{
n
=
mrb_dump_irep_binary
(
mrb
,
0
,
args
->
debug_info
,
wfp
);
}
if
(
n
!=
MRB_DUMP_OK
)
{
fprintf
(
stderr
,
"%s: error in mrb dump (%s) %d
\n
"
,
args
->
prog
,
outfile
,
n
);
}
return
n
;
}
int
main
(
int
argc
,
char
**
argv
)
{
mrb_state
*
mrb
=
mrb_open
();
int
n
=
-
1
;
struct
_args
args
;
mrbc_context
*
c
;
mrb_value
result
;
int
n
,
result
;
struct
mrbc_args
args
;
FILE
*
wfp
;
if
(
mrb
==
NULL
)
{
fputs
(
"Invalid mrb_state, exiting mrbc
\n
"
,
stderr
);
...
...
@@ -194,39 +243,58 @@ main(int argc, char **argv)
}
n
=
parse_args
(
mrb
,
argc
,
argv
,
&
args
);
if
(
n
==
EXIT_FAILURE
||
args
.
rfp
==
NULL
)
{
if
(
n
<
0
)
{
cleanup
(
mrb
,
&
args
);
usage
(
argv
[
0
]);
return
n
;
return
EXIT_FAILURE
;
}
if
(
n
==
argc
)
{
fprintf
(
stderr
,
"%s: no program file given
\n
"
,
args
.
prog
);
return
EXIT_FAILURE
;
}
if
(
args
.
outfile
==
NULL
)
{
if
(
n
+
1
==
argc
)
{
args
.
outfile
=
get_outfilename
(
mrb
,
argv
[
n
],
args
.
initname
?
C_EXT
:
RITEBIN_EXT
);
}
else
{
fprintf
(
stderr
,
"%s: output file should be specified to compile multiple files
\n
"
,
args
.
prog
);
return
EXIT_FAILURE
;
}
}
c
=
mrbc_context_new
(
mrb
);
if
(
args
.
verbose
)
c
->
dump_result
=
1
;
c
->
no_exec
=
1
;
c
->
filename
=
args
.
filename
;
result
=
mrb_load_file_cxt
(
mrb
,
args
.
rfp
,
c
);
if
(
mrb_undef_p
(
result
)
||
mrb_fixnum
(
result
)
<
0
)
{
args
.
idx
=
n
;
if
(
load_file
(
mrb
,
&
args
)
==
EXIT_FAILURE
)
{
cleanup
(
mrb
,
&
args
);
return
EXIT_FAILURE
;
}
if
(
args
.
check_syntax
)
{
puts
(
"Syntax OK"
);
printf
(
"%s:%s:Syntax OK"
,
args
.
prog
,
argv
[
n
]);
}
if
(
args
.
check_syntax
)
{
cleanup
(
mrb
,
&
args
);
return
EXIT_SUCCESS
;
}
if
(
args
.
initname
)
{
n
=
mrb_dump_irep_cfunc
(
mrb
,
n
,
args
.
debug_info
,
args
.
wfp
,
args
.
initname
);
if
(
n
==
MRB_DUMP_INVALID_ARGUMENT
)
{
printf
(
"%s: Invalid C language symbol name
\n
"
,
args
.
initname
);
if
(
args
.
outfile
)
{
if
(
strcmp
(
"-"
,
args
.
outfile
)
==
0
)
{
wfp
=
stdout
;
}
else
if
((
wfp
=
fopen
(
args
.
outfile
,
"w"
))
==
NULL
)
{
fprintf
(
stderr
,
"%s: cannot open output file:(%s)
\n
"
,
args
.
prog
,
args
.
outfile
);
return
EXIT_FAILURE
;
}
}
else
{
n
=
mrb_dump_irep_binary
(
mrb
,
n
,
args
.
debug_info
,
args
.
wfp
);
fprintf
(
stderr
,
"Output file is required
\n
"
);
return
EXIT_FAILURE
;
}
result
=
dump_file
(
mrb
,
wfp
,
args
.
outfile
,
&
args
);
fclose
(
wfp
);
cleanup
(
mrb
,
&
args
);
if
(
result
!=
MRB_DUMP_OK
)
{
return
EXIT_FAILURE
;
}
return
EXIT_SUCCESS
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment