├── .gitignore ├── AUTHORS ├── COPYING ├── COPYING.ja ├── ChangeLog ├── INSTALL ├── INSTALL.ja ├── LEGAL ├── MITL ├── MITL.ja ├── Makefile ├── NEWS ├── README ├── README.ja ├── Todo.txt ├── bin └── .gitkeep ├── doc └── .gitkeep ├── ext └── .gitkeep ├── include ├── mrbconf.h ├── mruby.h └── mruby │ ├── array.h │ ├── class.h │ ├── hash.h │ ├── numeric.h │ ├── object.h │ ├── proc.h │ ├── range.h │ ├── string.h │ └── struct.h ├── lib └── .gitkeep ├── mrblib ├── Makefile ├── array.rb ├── compar.rb ├── enum.rb ├── error.rb ├── hash.rb ├── init_mrblib.c ├── kernel.rb ├── numeric.rb ├── print.rb ├── range.rb ├── string.rb └── struct.rb ├── src ├── Makefile ├── array.c ├── ascii.c ├── cdump.c ├── cdump.h ├── class.c ├── codegen.c ├── compar.c ├── compile.h ├── crc.c ├── dump.c ├── dump.h ├── encoding.c ├── encoding.h ├── enum.c ├── error.c ├── error.h ├── etc.c ├── eval_intern.h ├── ext │ └── .gitkeep ├── gc.c ├── gc.h ├── hash.c ├── init.c ├── init_ext.c ├── irep.h ├── kernel.c ├── keywords ├── lex.def ├── load.c ├── mdata.h ├── method.h ├── minimain.c ├── name2ctype.h ├── node.h ├── numeric.c ├── object.c ├── oniguruma.h ├── opcode.h ├── parse.y ├── pool.c ├── pool.h ├── print.c ├── proc.c ├── range.c ├── re.c ├── re.h ├── regcomp.c ├── regenc.c ├── regenc.h ├── regerror.c ├── regex.h ├── regexec.c ├── regint.h ├── regparse.c ├── regparse.h ├── ritehash.h ├── sprintf.c ├── st.c ├── st.h ├── state.c ├── string.c ├── struct.c ├── symbol.c ├── transcode.c ├── transcode_data.h ├── unicode.c ├── us_ascii.c ├── utf_8.c ├── variable.c ├── variable.h ├── version.c ├── version.h ├── vm.c └── vm_core.h └── tools ├── mrbc ├── Makefile └── mrbc.c └── mruby ├── Makefile └── mruby.c /.gitignore: -------------------------------------------------------------------------------- 1 | # / 2 | *.bak 3 | *.dylib 4 | *.inc 5 | *.o 6 | *.orig 7 | *.rej 8 | *.sav 9 | *.swp 10 | *.d 11 | *~ 12 | .DS_Store 13 | .ccmalloc 14 | .svn 15 | /.git 16 | cscope.out 17 | mruby.exe 18 | y.tab.c 19 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Original Authors "mruby developers" are: 2 | Yukihiro Matsumoto 3 | FUKUOKA CSK CORPORATION 4 | Kyushu Institute of Technology 5 | Network Applied Communication Laboratory, Inc. 6 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | mRuby is copyrighted free software by mruby developers . 2 | You can redistribute it and/or modify it under either the terms of the 3 | MIT license (see the file MITL), or the conditions below: 4 | 5 | 1. You may make and give away verbatim copies of the source form of the 6 | software without restriction, provided that you duplicate all of the 7 | original copyright notices and associated disclaimers. 8 | 9 | 2. You may modify your copy of the software in any way, provided that 10 | you do at least ONE of the following: 11 | 12 | a) place your modifications in the Public Domain or otherwise 13 | make them Freely Available, such as by posting said 14 | modifications to Usenet or an equivalent medium, or by allowing 15 | the author to include your modifications in the software. 16 | 17 | b) use the modified software only within your corporation or 18 | organization. 19 | 20 | c) give non-standard binaries non-standard names, with 21 | instructions on where to get the original software distribution. 22 | 23 | d) make other distribution arrangements with the author. 24 | 25 | 3. You may distribute the software in object code or binary form, 26 | provided that you do at least ONE of the following: 27 | 28 | a) distribute the binaries and library files of the software, 29 | together with instructions (in the manual page or equivalent) 30 | on where to get the original distribution. 31 | 32 | b) accompany the distribution with the machine-readable source of 33 | the software. 34 | 35 | c) give non-standard binaries non-standard names, with 36 | instructions on where to get the original software distribution. 37 | 38 | d) make other distribution arrangements with the author. 39 | 40 | 4. You may modify and include the part of the software into any other 41 | software (possibly commercial). But some files in the distribution 42 | are not written by the author, so that they are not under these terms. 43 | 44 | For the list of those files and their copying conditions, see the 45 | file LEGAL. 46 | 47 | 5. The scripts and library files supplied as input to or produced as 48 | output from the software do not automatically fall under the 49 | copyright of the software, but belong to whomever generated them, 50 | and may be sold commercially, and may be aggregated with this 51 | software. 52 | 53 | 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR 54 | IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 55 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 56 | PURPOSE. 57 | -------------------------------------------------------------------------------- /COPYING.ja: -------------------------------------------------------------------------------- 1 | 本プログラムはフリーソフトウェアです.MITライセンス 2 | または以下に示す条件で本プログラムを再配布できます 3 | MITライセンスについてはMTILファイル(参考訳:MITL.ja)を 4 | 参照して下さい. 5 | 6 | 1. 複製は制限なく自由です. 7 | 8 | 2. 以下の条件のいずれかを満たす時に本プログラムのソースを 9 | 自由に変更できます. 10 | 11 | (a) ネットニューズにポストしたり,作者に変更を送付する 12 | などの方法で,変更を公開する. 13 | 14 | (b) 変更した本プログラムを自分の所属する組織内部だけで 15 | 使う. 16 | 17 | (c) 変更点を明示したうえ,ソフトウェアの名前を変更する. 18 | そのソフトウェアを配布する時には変更前の本プログラ 19 | ムも同時に配布する.または変更前の本プログラムのソー 20 | スの入手法を明示する. 21 | 22 | (d) その他の変更条件を作者と合意する. 23 | 24 | 3. 以下の条件のいずれかを満たす時に本プログラムをコンパイ 25 | ルしたオブジェクトコードや実行形式でも配布できます. 26 | 27 | (a) バイナリを受け取った人がソースを入手できるように, 28 | ソースの入手法を明示する. 29 | 30 | (b) 機械可読なソースコードを添付する. 31 | 32 | (c) 変更を行ったバイナリは名前を変更したうえ,オリジナ 33 | ルのソースコードの入手法を明示する. 34 | 35 | (d) その他の配布条件を作者と合意する. 36 | 37 | 4. 他のプログラムへの引用はいかなる目的であれ自由です.た 38 | だし,本プログラムに含まれる他の作者によるコードは,そ 39 | れぞれの作者の意向による制限が加えられる場合があります. 40 | 41 | それらファイルの一覧とそれぞれの配布条件などに付いては 42 | LEGALファイルを参照してください. 43 | 44 | 5. 本プログラムへの入力となるスクリプトおよび,本プログラ 45 | ムからの出力の権利は本プログラムの作者ではなく,それぞ 46 | れの入出力を生成した人に属します.また,本プログラムに 47 | 組み込まれるための拡張ライブラリについても同様です. 48 | 49 | 6. 本プログラムは無保証です.作者は本プログラムをサポート 50 | する意志はありますが,プログラム自身のバグあるいは本プ 51 | ログラムの実行などから発生するいかなる損害に対しても責 52 | 任を持ちません. 53 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | Thu Apl 19 17:25:18 2012 Yukihiro Matsumoto 2 | 3 | * first release version 1.0.0 released. 4 | 5 | Local variables: 6 | add-log-time-format: (lambda () 7 | (let* ((time (current-time)) 8 | (system-time-locale "C") 9 | (diff (+ (cadr time) 32400)) 10 | (lo (% diff 65536)) 11 | (hi (+ (car time) (/ diff 65536)))) 12 | (format-time-string "%a %b %e %H:%M:%S %Y" (list hi lo) t))) 13 | indent-tabs-mode: t 14 | tab-width: 8 15 | end: 16 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | * Compilation and Installation 2 | 3 | 1. Run make in top directory. 4 | 5 | This command will create following directories and 6 | store libraries and binaries files into them. 7 | 8 | * bin 9 | * lib 10 | * include 11 | 12 | If you fail to compile ruby, please send the detailed error report with 13 | the error log and machine/OS type, to help others. 14 | 15 | * Porting to other platforms 16 | 17 | 18 | 19 | That's all. 20 | -------------------------------------------------------------------------------- /INSTALL.ja: -------------------------------------------------------------------------------- 1 | * コンパイル・インストール 2 | 3 | 以下の手順で行ってください. 4 | 5 | 1. makeを実行してコンパイルする 6 | 7 | 以下のディレクトリにライブラリおよびバイナリが作成されます。 8 | 9 | * bin 10 | * lib 11 | 12 | もし,コンパイル時にエラーが発生した場合にはエラーのログとマ 13 | シン,OSの種類を含むできるだけ詳しいレポートを作者に送ってく 14 | ださると他の方のためにもなります. 15 | 16 | 17 | * 移植 18 | 19 | 20 | 以上 -------------------------------------------------------------------------------- /LEGAL: -------------------------------------------------------------------------------- 1 | LEGAL NOTICE INFORMATION 2 | ------------------------ 3 | 4 | All the files in this distribution are covered under the MIT license 5 | (see the file COPYING) except some files mentioned below: 6 | 7 | 8 | (currently no item are listed.) 9 | -------------------------------------------------------------------------------- /MITL: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 mruby developers 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /MITL.ja: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 mruby developers 2 | 3 | 以下に定める条件に従い、本ソフトウェアおよび関連文書のファイル(以下「ソフトウェア」)の複製を取得するすべての人に対し、ソフトウェアを無制限に扱うことを無償で許可します。これには、ソフトウェアの複製を使用、複写、変更、結合、掲載、頒布、サブライセンス、および/または販売する権利、およびソフトウェアを提供する相手に同じことを許可する権利も無制限に含まれます。 4 | 5 | 上記の著作権表示および本許諾表示を、ソフトウェアのすべての複製または重要な部分に記載するものとします。 6 | 7 | ソフトウェアは「現状のまま」で、明示であるか暗黙であるかを問わず、何らの保証もなく提供されます。ここでいう保証とは、商品性、特定の目的への適合性、および権利非侵害についての保証も含みますが、それに限定されるものではありません。 作者または著作権者は、契約行為、不法行為、またはそれ以外であろうと、ソフトウェアに起因または関連し、あるいはソフトウェアの使用またはその他の扱いによって生じる一切の請求、損害、その他の義務について何らの責任も負わないものとします。 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # makefile discription. 2 | # basic build file for Rite-VM(mruby) 3 | # 11.Apr.2011 coded by Kenji Yoshimoto. 4 | # 17.Jan.2012 coded by Hiroshi Mimaki. 5 | 6 | # project-specific macros 7 | # extension of the executable-file is modifiable(.exe .out ...) 8 | TARGET := bin/mrubysample 9 | RITEVM := lib/ritevm 10 | MRUBY := tools/mruby/mruby 11 | ifeq ($(OS),Windows_NT) 12 | EXE := $(TARGET).exe 13 | LIB := $(RITEVM).lib 14 | MRB := $(MRUBY).exe 15 | else 16 | EXE := $(TARGET) 17 | LIB := $(RITEVM).a 18 | MRB := $(MRUBY) 19 | endif 20 | MSRC := src/minimain.c 21 | YSRC := src/parse.y 22 | YC := src/y.tab.c 23 | EXCEPT1 := $(YC) $(MSRC) 24 | OBJM := $(patsubst %.c,%.o,$(MSRC)) 25 | OBJY := $(patsubst %.c,%.o,$(YC)) 26 | OBJ1 := $(patsubst %.c,%.o,$(filter-out $(EXCEPT1),$(wildcard src/*.c))) 27 | #OBJ2 := $(patsubst %.c,%.o,$(wildcard ext/regex/*.c)) 28 | #OBJ3 := $(patsubst %.c,%.o,$(wildcard ext/enc/*.c)) 29 | OBJS := $(OBJ1) $(OBJ2) $(OBJ3) 30 | # mruby libraries 31 | EXTC := mrblib/mrblib.c 32 | EXTRB := $(wildcard mrblib/*.rb) 33 | EXT0 := $(patsubst %.c,%.o,src/$(EXTC)) 34 | # ext libraries 35 | EXTS := $(EXT0) 36 | 37 | # libraries, includes 38 | LIBS = $(LIB) -lm 39 | INCLUDES = -I./src -I./include 40 | 41 | # library for iOS 42 | IOSLIB := $(RITEVM)-ios.a 43 | IOSSIMLIB := $(RITEVM)-iossim.a 44 | IOSDEVLIB := $(RITEVM)-iosdev.a 45 | IOSSIMCC := xcrun -sdk iphoneos llvm-gcc-4.2 -arch i386 -isysroot "/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/" 46 | IOSDEVCC := xcrun -sdk iphoneos llvm-gcc-4.2 -arch armv7 -isysroot "/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/" 47 | 48 | # compiler, linker (gcc) 49 | CC = gcc 50 | LL = gcc 51 | YACC = bison 52 | DEBUG_MODE = 1 53 | ifeq ($(DEBUG_MODE),1) 54 | CFLAGS = -g 55 | else 56 | CFLAGS = -O3 57 | endif 58 | ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS) 59 | MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL) 60 | 61 | ############################## 62 | # generic build targets, rules 63 | 64 | .PHONY : all 65 | all : $(LIB) $(MRB) $(EXE) 66 | @echo "make: built targets of `pwd`" 67 | 68 | ############################## 69 | # make library for iOS 70 | .PHONY : ios 71 | ios : $(IOSLIB) 72 | 73 | $(IOSLIB) : $(IOSSIMLIB) $(IOSDEVLIB) 74 | lipo -arch i386 $(IOSSIMLIB) -arch armv7 $(IOSDEVLIB) -create -output $(IOSLIB) 75 | 76 | $(IOSSIMLIB) : 77 | $(MAKE) clean -C src $(MAKE_FLAGS) 78 | $(MAKE) -C src $(MAKE_FLAGS) CC="$(IOSSIMCC)" LL="$(IOSSIMCC)" 79 | cp $(LIB) $(IOSSIMLIB) 80 | 81 | $(IOSDEVLIB) : 82 | $(MAKE) clean -C src $(MAKE_FLAGS) 83 | $(MAKE) -C src $(MAKE_FLAGS) CC="$(IOSDEVCC)" LL="$(IOSDEVCC)" 84 | cp $(LIB) $(IOSDEVLIB) 85 | 86 | # executable constructed using linker from object files 87 | $(EXE) : $(OBJM) $(LIB) 88 | $(LL) -o $@ $(OBJM) $(LIBS) 89 | 90 | -include $(OBJS:.o=.d) 91 | 92 | # src compile 93 | $(LIB) : $(EXTS) $(OBJS) $(OBJY) 94 | $(MAKE) -C src $(MAKE_FLAGS) 95 | 96 | # mruby interpreter compile 97 | $(MRB) : $(EXTS) $(OBJS) $(OBJY) 98 | $(MAKE) -C tools/mruby $(MAKE_FLAGS) 99 | 100 | # objects compiled from source 101 | $(OBJS) : 102 | $(MAKE) -C src $(MAKE_FLAGS) && $(MAKE) -C tools/mruby $(MAKE_FLAGS) 103 | 104 | # extend libraries complile 105 | $(EXTS) : $(EXTRB) 106 | $(MAKE) -C mrblib $(MAKE_FLAGS) 107 | 108 | # test module compile 109 | $(OBJM) : $(MSRC) 110 | $(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $(MSRC) -o $(OBJM) 111 | 112 | # clean up 113 | .PHONY : clean 114 | clean : 115 | $(MAKE) clean -C src $(MAKE_FLAGS) 116 | $(MAKE) clean -C tools/mruby $(MAKE_FLAGS) 117 | -rm -f $(EXE) $(OBJM) 118 | -rm -f $(OBJM:.o=.d) 119 | -rm -f $(IOSLIB) $(IOSSIMLIB) $(IOSDEVLIB) 120 | @echo "make: removing targets, objects and depend files of `pwd`" 121 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | * NEWS 2 | 3 | This document is a list of user visible feature changes made between 4 | releases except for bug fixes. 5 | 6 | Note that each entry is kept so brief that no reason behind or 7 | reference information is supplied with. For a full list of changes 8 | with all sufficient information, see the ChangeLog file. 9 | 10 | 11 | ** Information about first release v1.0.0 12 | 13 | 14 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | * What's mRuby 2 | 3 | mRuby is the ... 4 | 5 | * Features of mRuby 6 | 7 | + Simple Syntax 8 | + *Normal* Object-Oriented features(ex. class, method calls) 9 | + *Advanced* Object-Oriented features(ex. Mix-in, Singleton-method) 10 | + Operator Overloading 11 | + Exception Handling 12 | + Iterators and Closures 13 | + Garbage Collection 14 | + Dynamic Loading of Object files(on some architecture) 15 | + Highly Portable (works on many Unix-like/POSIX compatible platforms 16 | as well as Windows, Mac OS X, BeOS etc.) 17 | cf. http://redmine.ruby-lang.org/wiki/ruby-19/SupportedPlatforms 18 | 19 | 20 | * How to get mRuby 21 | 22 | The mRuby distribution files can be found in the following site: 23 | 24 | https://github.com/mruby/mruby/zipball/master 25 | 26 | The trunk of the mRuby source tree can be checked out with the 27 | following command: 28 | 29 | $ git ... 30 | 31 | There are some other branches under development. Try the following 32 | command and see the list of branches: 33 | 34 | $ git ... 35 | 36 | 37 | * mRuby home-page 38 | 39 | The URL of the mRuby home-page is: 40 | 41 | http://www.mruby.org/ 42 | 43 | 44 | * Mailing list 45 | 46 | There is a mailing list to talk about mRuby. 47 | To subscribe this list.... 48 | 49 | * How to compile and install 50 | 51 | See the file INSTALL. 52 | 53 | 54 | * Copying 55 | 56 | See the file COPYING. 57 | 58 | 59 | * The Author 60 | 61 | Feel free to send comments and bug reports to the author. Here is the 62 | author's latest mail address: 63 | 64 | devel@ruby.org 65 | 66 | ------------------------------------------------------- 67 | created at: Fri Apr 20 11:57:36 JST 2012 68 | Local variables: 69 | mode: indented-text 70 | end: 71 | -------------------------------------------------------------------------------- /README.ja: -------------------------------------------------------------------------------- 1 | * mRubyとは 2 | 3 | mRubyは経済産業省の… 4 | 5 | 6 | * mRubyの特長 7 | 8 | >以下要修正 9 | > + シンプルな文法 10 | > + 普通のオブジェクト指向機能(クラス,メソッドコールなど) 11 | > + 特殊なオブジェクト指向機能(Mixin, 特異メソッドなど) 12 | > + 演算子オーバーロード 13 | > + 例外処理機能 14 | > + イテレータとクロージャ 15 | > + ガーベージコレクタ 16 | > + ダイナミックローディング (アーキテクチャによる) 17 | > + 移植性が高い.多くのUnix-like/POSIX互換プラットフォーム上で 18 | > 動くだけでなく,Windows, Mac OS X,BeOSなどの上でも動く 19 | > cf. http://redmine.ruby-lang.org/wiki/ruby-19/SupportedPlatformsJa 20 | 21 | * 入手法 22 | 23 | ** Zipで 24 | 25 | 以下の場所においてあります. 26 | 27 | https://github.com/mruby/mruby/zipball/master 28 | 29 | ** GitHubで 30 | 31 | 開発先端のソースコードは次のコマンドで取得できます. 32 | 33 | $ git ….. 34 | 35 | 他に開発中のブランチの一覧は次のコマンドで見られます. 36 | 37 | $ git … 38 | 39 | 40 | * ホームページ 41 | 42 | mRubyのホームページのURLは 43 | 44 | http://www.mruby.org/ 45 | 46 | です. 47 | 48 | 49 | * メーリングリスト 50 | 51 | mRubyのメーリングリストがあります。参加希望の方は…. 52 | 53 | 54 | Ruby開発者向けメーリングリストもあります。こちらではrubyのバ 55 | グ、将来の仕様拡張など実装上の問題について議論されています。 56 | 参加希望の方は… 57 | 58 | 59 | 60 | * コンパイル・インストール・移植 61 | 62 | INSTALL.ja ファイルを参照してください。 63 | 64 | 65 | * 配布条件 66 | 67 | COPYING.ja ファイルを参照してください。 68 | 69 | 70 | * 著者 71 | 72 | コメント,バグレポートその他は devel@mruby.org まで. 73 | ------------------------------------------------------- 74 | created at: Fri Apr 20 11:57:36 JST 2012 75 | Local variables: 76 | mode: indented-text 77 | end: 78 | -------------------------------------------------------------------------------- /Todo.txt: -------------------------------------------------------------------------------- 1 | やること(まだできてないこと) / not yet complete 2 | 3 | * ヒアドキュメント / here document 4 | * 特殊変数 ($1,$2..) / special variables 5 | * super in aliased methods 6 | * BEGIN/END (対応しないんだっけ?) 7 | * const_missing 8 | * respond_to_missing 9 | 10 | 改善すること(できているが直すこと) 11 | 12 | * Hash (サイズを減らす。khashを使うか、順序を保存するか) 13 | * stringEx (encoding削除、CODERANGE削除、UTF-8 or ASCII以外削除) 14 | * 気づいたら書き加える 15 | -------------------------------------------------------------------------------- /bin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matz/mruby/8a5943f2540cf43bb15789bc519e1b355d479fed/bin/.gitkeep -------------------------------------------------------------------------------- /doc/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matz/mruby/8a5943f2540cf43bb15789bc519e1b355d479fed/doc/.gitkeep -------------------------------------------------------------------------------- /ext/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matz/mruby/8a5943f2540cf43bb15789bc519e1b355d479fed/ext/.gitkeep -------------------------------------------------------------------------------- /include/mrbconf.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBYCONF_H 2 | #define MRUBYCONF_H 3 | 4 | #include 5 | typedef double mrb_float; 6 | typedef int32_t mrb_int; 7 | typedef intptr_t mrb_sym; 8 | 9 | #define readint(p,base) strtol((p),NULL,(base)) 10 | #define readfloat(p) strtod((p),NULL) 11 | 12 | #undef INCLUDE_ENCODING /* not use encoding classes (ascii only) */ 13 | #define INCLUDE_ENCODING /* use UTF-8 encoding classes */ 14 | 15 | #undef INCLUDE_REGEXP /* not use regular expression classes */ 16 | #define INCLUDE_REGEXP /* use regular expression classes */ 17 | 18 | #ifdef INCLUDE_REGEXP 19 | # define INCLUDE_ENCODING /* Regexp depends Encoding */ 20 | #endif 21 | 22 | #undef HAVE_UNISTD_H /* WINDOWS */ 23 | #define HAVE_UNISTD_H /* LINUX */ 24 | 25 | #define SIZEOF_INT 4 26 | #define SIZEOF_SHORT 2 27 | #define SIZEOF_LONG 4 28 | #define SIZEOF_LONG_LONG 8 29 | #define SIZEOF___INT64 0 30 | #define SIZEOF_VOIDP 4 31 | #define SIZEOF_FLOAT 4 32 | #define SIZEOF_DOUBLE 8 33 | 34 | #ifndef FALSE 35 | # define FALSE 0 36 | #endif 37 | 38 | #ifndef TRUE 39 | # define TRUE 1 40 | #endif 41 | 42 | #endif /* MRUBYCONF_H */ 43 | -------------------------------------------------------------------------------- /include/mruby/array.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_ARRAY_H 2 | #define MRUBY_ARRAY_H 3 | 4 | struct RArray { 5 | MRUBY_OBJECT_HEADER; 6 | size_t len; 7 | size_t capa; 8 | mrb_value *buf; 9 | }; 10 | 11 | #define mrb_ary_ptr(v) ((struct RArray*)((v).value.p)) 12 | #define mrb_ary_value(p) mrb_obj_value((void*)(p)) 13 | #define RARRAY(v) ((struct RArray*)((v).value.p)) 14 | 15 | #define RARRAY_LEN(a) (RARRAY(a)->len) 16 | #define RARRAY_PTR(a) (RARRAY(a)->buf) 17 | 18 | mrb_value mrb_ary_new_capa(mrb_state*, size_t); 19 | mrb_value mrb_ary_new(mrb_state *mrb); 20 | mrb_value mrb_ary_new_elts(mrb_state *mrb, long n, const mrb_value *elts); 21 | void mrb_ary_concat(mrb_state*, mrb_value, mrb_value); 22 | mrb_value mrb_ary_splat(mrb_state*, mrb_value); 23 | void mrb_ary_push(mrb_state*, mrb_value, mrb_value); 24 | mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary); 25 | mrb_value mrb_ary_new_from_values(mrb_state *mrb, mrb_value *vals, size_t size); 26 | mrb_value mrb_ary_aget(mrb_state *mrb, mrb_value self); 27 | mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n); 28 | void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val); 29 | int mrb_ary_len(mrb_state *mrb, mrb_value ary); 30 | mrb_value mrb_ary_replace_m(mrb_state *mrb, mrb_value self); 31 | void mrb_ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, size_t len); 32 | mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self); 33 | mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item); 34 | mrb_value mrb_ary_new4(mrb_state *mrb, long n, const mrb_value *elts); 35 | mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr); 36 | mrb_value mrb_ary_entry(mrb_value ary, long offset); 37 | void mrb_mem_clear(mrb_value *mem, long size); 38 | mrb_value mrb_ary_tmp_new(mrb_state *mrb, long capa); 39 | mrb_value mrb_ary_sort(mrb_state *mrb, mrb_value ary); 40 | mrb_value mrb_ary_shift(mrb_state *mrb, mrb_value self); 41 | 42 | #endif /* MRUBY_ARRAY_H */ 43 | -------------------------------------------------------------------------------- /include/mruby/class.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_CLASS_H 2 | #define MRUBY_CLASS_H 3 | 4 | struct RClass { 5 | MRUBY_OBJECT_HEADER; 6 | struct kh_iv *iv; 7 | struct kh_mt *mt; 8 | struct RClass *super; 9 | }; 10 | 11 | #define mrb_class_ptr(v) ((struct RClass*)((v).value.p)) 12 | #define RCLASS_SUPER(v) (((struct RClass*)((v).value.p))->super) 13 | #define RCLASS_IV_TBL(v) (((struct RClass*)((v).value.p))->iv) 14 | #define RCLASS_M_TBL(v) (((struct RClass*)((v).value.p))->mt) 15 | 16 | static inline struct RClass* 17 | mrb_class(mrb_state *mrb, mrb_value v) 18 | { 19 | switch (mrb_type(v)) { 20 | case MRB_TT_FALSE: 21 | if (v.value.p) 22 | return mrb->false_class; 23 | return mrb->nil_class; 24 | case MRB_TT_TRUE: 25 | return mrb->true_class; 26 | case MRB_TT_SYMBOL: 27 | return mrb->symbol_class; 28 | case MRB_TT_FIXNUM: 29 | return mrb->fixnum_class; 30 | case MRB_TT_FLOAT: 31 | return mrb->float_class; 32 | 33 | #ifdef INCLUDE_REGEXP 34 | // case MRB_TT_REGEX: 35 | // return mrb->regex_class; 36 | // case MRB_TT_MATCH: 37 | // return mrb->match_class; 38 | // case MRB_TT_DATA: 39 | // return mrb->encode_class; 40 | #else 41 | case MRB_TT_REGEX: 42 | case MRB_TT_MATCH: 43 | mrb_raise(mrb, E_TYPE_ERROR, "type mismatch: %s given", 44 | mrb_obj_classname(mrb, v)); 45 | return mrb->nil_class; /* not reach */ 46 | #endif 47 | default: 48 | return ((struct RBasic*)mrb_object(v))->c; 49 | } 50 | } 51 | 52 | #define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~0xff) | (char)tt) 53 | #define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & 0xff) 54 | 55 | struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*); 56 | struct RClass* mrb_define_module_id(mrb_state*, mrb_sym); 57 | struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym); 58 | struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym); 59 | void mrb_define_method_vm(mrb_state*, struct RClass*, mrb_sym, mrb_value); 60 | void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, struct RProc *); 61 | 62 | struct RClass *mrb_class_outer_module(mrb_state*, struct RClass *); 63 | struct RProc *mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym); 64 | struct RProc *mrb_method_search(mrb_state*, struct RClass*, mrb_sym); 65 | 66 | int mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid); 67 | void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, int aspec); 68 | 69 | void mrb_obj_call_init(mrb_state *mrb, mrb_value obj, int argc, mrb_value *argv); 70 | 71 | #endif /* MRUBY_CLASS_H */ 72 | -------------------------------------------------------------------------------- /include/mruby/hash.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_HASH_H 2 | #define MRUBY_HASH_H 3 | 4 | struct RHash { 5 | MRUBY_OBJECT_HEADER; 6 | struct kh_ht *ht; 7 | mrb_value ifnone; 8 | }; 9 | 10 | #define N 624 11 | #define M 397 12 | #define MATRIX_A 0x9908b0dfU /* constant vector a */ 13 | #define UMASK 0x80000000U /* most significant w-r bits */ 14 | #define LMASK 0x7fffffffU /* least significant r bits */ 15 | #define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) ) 16 | #define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1U ? MATRIX_A : 0U)) 17 | enum {MT_MAX_STATE = N}; 18 | 19 | struct MT { 20 | /* assume int is enough to store 32bits */ 21 | unsigned int state[N]; /* the array for the state vector */ 22 | unsigned int *next; 23 | int left; 24 | }; 25 | 26 | #define mrb_hash_end(h) st_hash_end(h) 27 | #define mrb_hash_uint(h, i) st_hash_uint(h, i) 28 | 29 | #define mrb_hash_ptr(v) ((struct RHash*)((v).value.p)) 30 | #define mrb_hash_value(p) mrb_obj_value((void*)(p)) 31 | 32 | mrb_value mrb_hash_new_capa(mrb_state*, size_t); 33 | mrb_value mrb_hash_new(mrb_state *mrb, int capa); 34 | 35 | void mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val); 36 | mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key); 37 | mrb_value mrb_hash_getWithDef(mrb_state *mrb, mrb_value hash, mrb_value vkey, mrb_value def); 38 | mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key); 39 | mrb_value mrb_hash(mrb_state *mrb, mrb_value obj); 40 | void ruby_setenv(mrb_state *mrb, const char *name, const char *value); 41 | 42 | /* RHASH_TBL allocates st_table if not available. */ 43 | #define RHASH(obj) ((struct RHash*)((obj).value.p)) 44 | #define RHASH_TBL(h) mrb_hash_tbl(h) 45 | #define RHASH_H_TBL(h) (RHASH(h)->ht) 46 | #define RHASH_SIZE(h) (RHASH_H_TBL(h)->size) 47 | #define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0) 48 | #define RHASH_IFNONE(h) (RHASH(h)->ifnone) 49 | #define RHASH_PROCDEFAULT(h) (RHASH(h)->ifnone) 50 | struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash); 51 | 52 | #define MRB_HASH_PROC_DEFAULT 256 53 | #define MRB_RHASH_PROCDEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_PROC_DEFAULT) 54 | 55 | char * ruby_strdup(const char *str); 56 | void mrb_reset_random_seed(void); 57 | mrb_value mrb_obj_is_proc(mrb_value proc); 58 | 59 | #endif /* MRUBY_HASH_H */ 60 | -------------------------------------------------------------------------------- /include/mruby/numeric.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_NUMERIC_H 2 | #define MRUBY_NUMERIC_H 3 | 4 | #include 5 | 6 | #define RSHIFT(x,y) ((x)>>(int)(y)) 7 | #define FIXNUM_MAX (LONG_MAX>>1) 8 | #define FIXNUM_MIN RSHIFT((long)LONG_MIN,1) 9 | #define POSFIXABLE(f) ((f) < FIXNUM_MAX+1) 10 | #define NEGFIXABLE(f) ((f) >= FIXNUM_MIN) 11 | #define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f)) 12 | 13 | mrb_value mrb_dbl2big(mrb_state *mrb, float d); 14 | void mrb_num_zerodiv(mrb_state *mrb); 15 | mrb_value mrb_fix2str(mrb_state *mrb, mrb_value x, int base); 16 | 17 | #endif /* MRUBY_NUMERIC_H */ 18 | -------------------------------------------------------------------------------- /include/mruby/object.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_OBJECT_H 2 | #define MRUBY_OBJECT_H 3 | 4 | #define MRUBY_OBJECT_HEADER \ 5 | enum mrb_vtype tt:8;\ 6 | int color:3;\ 7 | unsigned int flags:21;\ 8 | struct RClass *c;\ 9 | struct RBasic *gcnext; 10 | 11 | 12 | /* white: 011, black: 100, gray: 000 */ 13 | #define MRB_GC_GRAY 0 14 | #define MRB_GC_WHITE_A 1 15 | #define MRB_GC_WHITE_B (1 << 1) 16 | #define MRB_GC_BLACK (1 << 2) 17 | #define MRB_GC_WHITES (MRB_GC_WHITE_A | MRB_GC_WHITE_B) 18 | #define MRB_GC_COLOR_MASK 7 19 | 20 | #define paint_gray(o) ((o)->color = MRB_GC_GRAY) 21 | #define paint_black(o) ((o)->color = MRB_GC_BLACK) 22 | #define paint_white(o) ((o)->color = MRB_GC_WHITES) 23 | #define paint_partial_white(s, o) ((o)->color = (s)->current_white_part) 24 | #define is_gray(o) ((o)->color == MRB_GC_GRAY) 25 | #define is_white(o) ((o)->color & MRB_GC_WHITES) 26 | #define is_black(o) ((o)->color & MRB_GC_BLACK) 27 | #define is_dead(s, o) (((o)->color & other_white_part(s) & MRB_GC_WHITES) || (o)->tt == MRB_TT_FREE) 28 | #define flip_white_part(s) ((s)->current_white_part = other_white_part(s)) 29 | #define other_white_part(s) ((s)->current_white_part ^ MRB_GC_WHITES) 30 | 31 | struct RBasic { 32 | MRUBY_OBJECT_HEADER; 33 | }; 34 | 35 | struct RObject { 36 | MRUBY_OBJECT_HEADER; 37 | struct kh_iv *iv; 38 | }; 39 | 40 | #define mrb_obj_ptr(v) ((struct RObject*)((v).value.p)) 41 | #define RBASIC(obj) ((struct RBasic*)((obj).value.p)) 42 | #define RBASIC_KLASS(v) ((struct RClass *)(((struct RBasic*)((v).value.p))->c)) 43 | #define ROBJECT(v) ((struct RObject*)((v).value.p)) 44 | #define ROBJECT_IVPTR(v) (((struct RObject*)((v).value.p))->iv) 45 | #define ROBJECT_NUMIV(v) (ROBJECT_IVPTR(v) ? ROBJECT_IVPTR(v)->size : 0) 46 | #endif /* MRUBY_OBJECT_H */ 47 | -------------------------------------------------------------------------------- /include/mruby/proc.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_PROC_H 2 | #define MRUBY_PROC_H 3 | 4 | #include "mruby.h" 5 | #include "irep.h" 6 | 7 | struct REnv { 8 | MRUBY_OBJECT_HEADER; 9 | mrb_value *stack; 10 | mrb_sym mid; 11 | int cioff; 12 | }; 13 | 14 | struct RProc { 15 | MRUBY_OBJECT_HEADER; 16 | union { 17 | mrb_irep *irep; 18 | mrb_func_t func; 19 | } body; 20 | struct RClass *target_class; 21 | struct REnv *env; 22 | }; 23 | 24 | /* aspec access */ 25 | #define ARGS_GETREQ(a) (((a) >> 19) & 0x1f) 26 | #define ARGS_GETOPT(a) (((a) >> 14) & 0x1f) 27 | #define ARGS_GETREST(a) ((a) & (1<<13)) 28 | #define ARGS_GETPOST(a) (((a) >> 8) & 0x1f) 29 | #define ARGS_GETKEY(a) (((a) >> 3) & 0x1f)) 30 | #define ARGS_GETKDICT(a) ((a) & (1<<2)) 31 | #define ARGS_GETBLOCK(a) ((a) & (1<<1)) 32 | 33 | #define MRB_PROC_CFUNC 128 34 | #define MRB_PROC_CFUNC_P(p) ((p)->flags & MRB_PROC_CFUNC) 35 | #define MRB_PROC_STRICT 256 36 | #define MRB_PROC_STRICT_P(p) ((p)->flags & MRB_PROC_STRICT) 37 | 38 | #define mrb_proc_ptr(v) ((struct RProc*)((v).value.p)) 39 | 40 | struct RProc *mrb_proc_new(mrb_state*, mrb_irep*); 41 | struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t); 42 | struct RProc *mrb_closure_new(mrb_state*, mrb_irep*); 43 | 44 | #endif /* MRUBY_STRING_H */ 45 | -------------------------------------------------------------------------------- /include/mruby/range.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_RANGE_H 2 | #define MRUBY_RANGE_H 3 | 4 | struct RRange { 5 | MRUBY_OBJECT_HEADER; 6 | struct mrb_range_edges { 7 | mrb_value beg; 8 | mrb_value end; 9 | } *edges; 10 | int excl; 11 | }; 12 | 13 | #define mrb_range_ptr(v) ((struct RRange*)((v).value.p)) 14 | #define mrb_range_value(p) mrb_obj_value((void*)(p)) 15 | 16 | mrb_value mrb_range_new(mrb_state*, mrb_value, mrb_value, int); 17 | mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_int err); 18 | int mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c); 19 | struct RClass* mrb_class_real(struct RClass* cl); 20 | 21 | #endif /* MRUBY_RANGE_H */ 22 | -------------------------------------------------------------------------------- /include/mruby/string.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_STRING_H 2 | #define MRUBY_STRING_H 3 | 4 | #ifdef INCLUDE_ENCODING 5 | #include "encoding.h" 6 | #endif 7 | 8 | #ifndef RB_GC_GUARD 9 | #define RB_GC_GUARD(v) v 10 | #endif 11 | 12 | #define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{')) 13 | 14 | #define mrb_str_new4 mrb_str_new_frozen 15 | 16 | #define STR_BUF_MIN_SIZE 128 17 | //#define RSTRING_EMBED_LEN_MAX STR_BUF_MIN_SIZE 18 | 19 | extern const char ruby_digitmap[]; 20 | 21 | struct RString { 22 | MRUBY_OBJECT_HEADER; 23 | size_t len; 24 | union { 25 | size_t capa; 26 | mrb_value shared; 27 | } aux; 28 | char *buf; 29 | }; 30 | 31 | extern struct SCOPE { 32 | struct RBasic super; 33 | mrb_sym *local_tbl; 34 | mrb_value *local_vars; 35 | int flags; 36 | } *ruby_scope; 37 | 38 | struct RVarmap { 39 | struct RBasic super; 40 | mrb_sym id; 41 | mrb_value val; 42 | struct RVarmap *next; 43 | }; 44 | extern struct RVarmap *ruby_dyna_vars; 45 | 46 | //struct st_hash_type { 47 | // int (*compare)(); 48 | // int (*hash)(); 49 | //}; 50 | 51 | #define mrb_str_ptr(s) ((struct RString*)((s).value.p)) 52 | #define RSTRING(s) ((struct RString*)((s).value.p)) 53 | #define RSTRING_PTR(s) (RSTRING(s)->buf) 54 | #define RSTRING_LEN(s) (RSTRING(s)->len) 55 | #define RSTRING_CAPA(s) (RSTRING(s)->aux.capa) 56 | #define RSTRING_SHARED(s) (RSTRING(s)->aux.shared) 57 | #define RSTRING_END(s) (RSTRING(s)->buf + RSTRING(s)->len) 58 | 59 | #define MRB_STR_SHARED 256 60 | #define MRB_STR_SHARED_P(s) (FL_ALL(s, MRB_STR_SHARED)) 61 | #define MRB_STR_NOCAPA (MRB_STR_SHARED) 62 | #define MRB_STR_NOCAPA_P(s) (FL_ANY(s, MRB_STR_NOCAPA)) 63 | #define MRB_STR_UNSET_NOCAPA(s) do {\ 64 | FL_UNSET(s, MRB_STR_NOCAPA);\ 65 | } while (0) 66 | 67 | mrb_value mrb_str_literal(mrb_state*, mrb_value); 68 | void mrb_str_concat(mrb_state*, mrb_value, mrb_value); 69 | mrb_value mrb_obj_to_str(mrb_state*, mrb_value); 70 | mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value); 71 | mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj); 72 | mrb_value mrb_str_new(mrb_state *mrb, const char *p, size_t len); /* mrb_str_new */ 73 | mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, size_t len); /* mrb_str_resize */ 74 | mrb_value mrb_string_value(mrb_state *mrb, mrb_value *ptr); /* StringValue */ 75 | mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, int len); 76 | mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str); 77 | mrb_value mrb_str_buf_new(mrb_state *mrb, size_t capa); 78 | mrb_value mrb_str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len); 79 | mrb_value str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len); 80 | 81 | char * mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr); 82 | char * mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr); 83 | mrb_value mrb_str_subseq(mrb_state *mrb, mrb_value str, long beg, long len); 84 | size_t mrb_str_sublen(mrb_state *mrb, mrb_value str, long pos); 85 | mrb_value mrb_str_size(mrb_state *mrb, mrb_value self); 86 | long mrb_str_offset(mrb_state *mrb, mrb_value str, long pos); 87 | mrb_value mrb_str_new2(mrb_state *mrb, const char *p); 88 | mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str); /* mrb_str_dup */ 89 | mrb_value mrb_str_new_frozen(mrb_state *mrb, mrb_value orig); 90 | mrb_value mrb_lastline_get(mrb_state *mrb); 91 | mrb_value mrb_usascii_str_new(mrb_state *mrb, const char *ptr, long len); 92 | void mrb_lastline_set(mrb_value val); 93 | mrb_value mrb_str_buf_cat_ascii(mrb_state *mrb, mrb_value str, const char *ptr); 94 | void mrb_str_modify(mrb_state *mrb, mrb_value str); 95 | void mrb_str_set_len(mrb_state *mrb, mrb_value str, long len); 96 | mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self); 97 | void mrb_str_shared_replace(mrb_state *mrb, mrb_value str, mrb_value str2); 98 | mrb_value mrb_str_cat2(mrb_state *mrb, mrb_value str, const char *ptr); 99 | mrb_value mrb_str_catf(mrb_state *mrb, mrb_value str, const char *format, ...); 100 | mrb_value mrb_str_to_inum(mrb_state *mrb, mrb_value str, int base, int badcheck); 101 | double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, int badcheck); 102 | mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str); 103 | mrb_value mrb_locale_str_new(mrb_state *mrb, const char *ptr, long len); 104 | mrb_value mrb_filesystem_str_new_cstr(mrb_state *mrb, const char *ptr); 105 | mrb_int mrb_str_hash(mrb_state *mrb, mrb_value str); 106 | int mrb_str_hash_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2); 107 | mrb_value str_new3(mrb_state *mrb, struct RClass* klass, mrb_value str); 108 | mrb_value mrb_str_buf_append(mrb_state *mrb, mrb_value str, mrb_value str2); 109 | void mrb_str_setter(mrb_state *mrb, mrb_value val, mrb_sym id, mrb_value *var); 110 | int mrb_str_is_ascii_only_p(mrb_state *mrb, mrb_value str); 111 | mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); 112 | int mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2); 113 | mrb_value str_new4(mrb_state *mrb, enum mrb_vtype ttype, mrb_value str); 114 | mrb_value * mrb_svar(mrb_int cnt); 115 | mrb_value mrb_str_drop_bytes(mrb_state *mrb, mrb_value str, long len); 116 | mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str); 117 | mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, long len); 118 | mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2); 119 | size_t mrb_str_capacity(mrb_value str); 120 | 121 | #ifdef INCLUDE_ENCODING 122 | int sym_printable(mrb_state *mrb, const char *s, const char *send, mrb_encoding *enc); 123 | mrb_value mrb_str_conv_enc(mrb_state *mrb, mrb_value str, mrb_encoding *from, mrb_encoding *to); 124 | mrb_value mrb_str_conv_enc_opts(mrb_state *mrb, mrb_value str, mrb_encoding *from, mrb_encoding *to, int ecflags, mrb_value ecopts); 125 | mrb_value mrb_enc_str_new(mrb_state *mrb, const char *ptr, long len, mrb_encoding *enc); 126 | #else 127 | int mrb_symname_p(const char *name); 128 | #endif 129 | 130 | mrb_value mrb_tainted_str_new(mrb_state *mrb, const char *ptr, long len); 131 | int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2); 132 | 133 | #endif /* MRUBY_STRING_H */ 134 | -------------------------------------------------------------------------------- /include/mruby/struct.h: -------------------------------------------------------------------------------- 1 | #ifndef MSTRUCT_H 2 | #define MSTRUCT_H 3 | 4 | struct RStruct { 5 | struct RBasic basic; 6 | long len; 7 | mrb_value *ptr; 8 | }; 9 | #define RSTRUCT(st) ((struct RStruct*)((st).value.p)) 10 | #define RSTRUCT_LEN(st) ((int)(RSTRUCT(st)->len)) 11 | #define RSTRUCT_PTR(st) (RSTRUCT(st)->ptr) 12 | 13 | mrb_value mrb_yield_values(int n, ...); 14 | mrb_value mrb_mod_module_eval(mrb_state *mrb, int argc, mrb_value *argv, mrb_value mod); 15 | 16 | #endif //MSTRUCT_H 17 | -------------------------------------------------------------------------------- /lib/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matz/mruby/8a5943f2540cf43bb15789bc519e1b355d479fed/lib/.gitkeep -------------------------------------------------------------------------------- /mrblib/Makefile: -------------------------------------------------------------------------------- 1 | # makefile discription. 2 | # basic build file for RiteVM library 3 | # 11.Oct.2011 coded by Hiroshi Mimaki. 4 | 5 | # project-specific macros 6 | # extension of the executable-file is modifiable(.exe .out ...) 7 | BASEDIR = . 8 | TARGET := mrblib 9 | MLIB := $(TARGET).o 10 | CLIB := $(TARGET).c 11 | DLIB := $(TARGET).ctmp 12 | RLIB := $(TARGET).rbtmp 13 | MRB1 := $(BASEDIR)/*.rb 14 | MRBS := $(MRB1) 15 | 16 | # C compiler (gcc) 17 | CC = gcc 18 | LL = gcc 19 | DEBUG_MODE = 1 20 | ifeq ($(DEBUG_MODE),1) 21 | CFLAGS = -g 22 | else 23 | CFLAGS = -O3 24 | endif 25 | INCLUDES = -I../src -I../include 26 | ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS) 27 | MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL) 28 | 29 | # mruby compiler 30 | ifeq ($(OS),Windows_NT) 31 | MRBC = ../bin/mrbc.exe 32 | else 33 | MRBC = ../bin/mrbc 34 | endif 35 | 36 | ############################## 37 | # generic build targets, rules 38 | 39 | .PHONY : all 40 | all : $(MRBC) $(MLIB) 41 | @echo "make: built targets of `pwd`" 42 | 43 | # Compile mrblib source 44 | $(MLIB) : $(CLIB) 45 | $(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $(CLIB) -o $(MLIB) 46 | 47 | # Compile C source from merged mruby source 48 | $(CLIB) : $(RLIB) $(MRBC) 49 | $(MRBC) -Bmrblib_irep -o$(DLIB) $(RLIB); cat init_$(TARGET).c $(DLIB) > $@ 50 | 51 | $(MRBC) : ../src/opcode.h ../src/codegen.c ../src/parse.y 52 | $(MAKE) -C ../tools/mrbc $(MAKE_FLAGS) 53 | 54 | # merge mruby sources 55 | $(RLIB) : $(MRBS) 56 | cat $? > $@ 57 | 58 | # clean up 59 | .PHONY : clean 60 | clean : 61 | -rm -f $(MRBC) $(MLIB) $(CLIB) $(RLIB) $(DLIB) 62 | @echo "make: removing targets, objects and depend files of `pwd`" 63 | 64 | -------------------------------------------------------------------------------- /mrblib/array.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Array 3 | # 4 | class Array 5 | # 15.2.12.5.10 6 | def each(&block) 7 | idx = 0 8 | while(idx < length) 9 | block.call(self[idx]) 10 | idx += 1 11 | end 12 | self 13 | end 14 | 15 | # 15.2.12.5.11 16 | def each_index(&block) 17 | idx = 0 18 | while(idx < length) 19 | block.call(idx) 20 | idx += 1 21 | end 22 | self 23 | end 24 | 25 | # 15.2.12.5.7 26 | def collect!(&block) 27 | self.each_index{|idx| 28 | self[idx] = block.call(self[idx]) 29 | } 30 | self 31 | end 32 | 33 | # 15.2.12.5.20 34 | # map!(&block) 35 | alias map! collect! 36 | 37 | # 15.2.12.5.15 38 | def initialize(size=0, obj=nil, &block) 39 | raise TypeError, "expected Integer for 1st argument" unless size.kind_of? Integer 40 | raise ArgumentError, "negative array size" if size < 0 41 | 42 | self.clear 43 | if size > 0 44 | self[size - 1] = nil # allocate 45 | 46 | idx = 0 47 | while(idx < size) 48 | self[idx] = (block)? block.call(idx): obj 49 | idx += 1 50 | end 51 | end 52 | 53 | self 54 | end 55 | 56 | def delete(key, &block) 57 | while i = self.index(key) 58 | self.delete_at(i) 59 | ret = key 60 | end 61 | if ret == nil && block 62 | block.call 63 | else 64 | ret 65 | end 66 | end 67 | end 68 | 69 | # include modules 70 | module Enumerable; end 71 | module Comparable; end 72 | class Array 73 | include Enumerable 74 | include Comparable 75 | 76 | def sort!(&block) 77 | self.replace(self.sort(&block)) 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /mrblib/compar.rb: -------------------------------------------------------------------------------- 1 | ### move to compar.c 2 | # module Comparable 3 | # def == other 4 | # cmp = self <=> other 5 | # if cmp == 0 6 | # true 7 | # else 8 | # false 9 | # end 10 | # end 11 | 12 | # def < other 13 | # cmp = self <=> other 14 | # if cmp.nil? 15 | # false 16 | # elsif cmp < 0 17 | # true 18 | # else 19 | # false 20 | # end 21 | # end 22 | 23 | # def <= other 24 | # cmp = self <=> other 25 | # if cmp.nil? 26 | # false 27 | # elsif cmp <= 0 28 | # true 29 | # else 30 | # false 31 | # end 32 | # end 33 | 34 | # def > other 35 | # cmp = self <=> other 36 | # if cmp.nil? 37 | # false 38 | # elsif cmp > 0 39 | # true 40 | # else 41 | # false 42 | # end 43 | # end 44 | 45 | # def >= other 46 | # cmp = self <=> other 47 | # if cmp.nil? 48 | # false 49 | # elsif cmp >= 0 50 | # true 51 | # else 52 | # false 53 | # end 54 | # end 55 | 56 | # def between?(min,max) 57 | # if self < min or self > max 58 | # false 59 | # else 60 | # true 61 | # end 62 | # end 63 | # end 64 | -------------------------------------------------------------------------------- /mrblib/enum.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Enumerable 3 | # 4 | module Enumerable 5 | # 15.3.2.2.1 6 | def all?(&block) 7 | st = true 8 | if block 9 | self.each{|val| 10 | unless block.call(val) 11 | st = false 12 | break 13 | end 14 | } 15 | else 16 | self.each{|val| 17 | unless val 18 | st = false 19 | break 20 | end 21 | } 22 | end 23 | st 24 | end 25 | 26 | # 15.3.2.2.2 27 | def any?(&block) 28 | st = false 29 | if block 30 | self.each{|val| 31 | if block.call(val) 32 | st = true 33 | break 34 | end 35 | } 36 | else 37 | self.each{|val| 38 | if val 39 | st = true 40 | break 41 | end 42 | } 43 | end 44 | st 45 | end 46 | 47 | # 15.3.2.2.3 48 | def collect(&block) 49 | ary = [] 50 | self.each{|val| 51 | ary.push(block.call(val)) 52 | } 53 | ary 54 | end 55 | 56 | # 15.3.2.2.4 57 | def detect(ifnone=nil, &block) 58 | ret = ifnone 59 | self.each{|val| 60 | if block.call(val) 61 | ret = val 62 | break 63 | end 64 | } 65 | ret 66 | end 67 | 68 | # 15.3.2.2.5 69 | def each_with_index(&block) 70 | i = 0 71 | self.each{|val| 72 | block.call(val, i) 73 | i += 1 74 | } 75 | self 76 | end 77 | 78 | # 15.3.2.2.6 79 | def entries 80 | ary = [] 81 | self.each{|val| 82 | ary.push val 83 | } 84 | ary 85 | end 86 | 87 | # 15.3.2.2.7 88 | # find(ifnone=nil, &block) 89 | alias find detect 90 | 91 | # 15.3.2.2.8 92 | def find_all(&block) 93 | ary = [] 94 | self.each{|val| 95 | ary.push(val) if block.call(val) 96 | } 97 | ary 98 | end 99 | 100 | # 15.3.2.2.9 101 | def grep(pattern, &block) 102 | ary = [] 103 | self.each{|val| 104 | if pattern === val 105 | ary.push((block)? block.call(val): val) 106 | end 107 | } 108 | ary 109 | end 110 | 111 | # 15.3.2.2.10 112 | def include?(obj) 113 | st = false 114 | self.each{|val| 115 | if val == obj 116 | st = true 117 | break 118 | end 119 | } 120 | st 121 | end 122 | 123 | # 15.3.2.2.11 124 | def inject(*args, &block) 125 | raise ArgumentError, "too many arguments" if args.size > 2 126 | flag = true # 1st element? 127 | result = nil 128 | self.each{|val| 129 | if flag 130 | # 1st element 131 | result = (args.empty?)? val: block.call(args[0], val) 132 | flag = false 133 | else 134 | result = block.call(result, val) 135 | end 136 | } 137 | result 138 | end 139 | 140 | # 15.3.2.2.12 141 | # map(&block) 142 | alias map collect 143 | 144 | # 15.3.2.2.13 145 | def max(&block) 146 | flag = true # 1st element? 147 | result = nil 148 | self.each{|val| 149 | if flag 150 | # 1st element 151 | result = val 152 | flag = false 153 | else 154 | if block 155 | result = val if block.call(val, result) > 0 156 | else 157 | result = val if (val <=> result) > 0 158 | end 159 | end 160 | } 161 | result 162 | end 163 | 164 | # 15.3.2.2.14 165 | def min(&block) 166 | flag = true # 1st element? 167 | result = nil 168 | self.each{|val| 169 | if flag 170 | # 1st element 171 | result = val 172 | flag = false 173 | else 174 | if block 175 | result = val if block.call(val, result) < 0 176 | else 177 | result = val if (val <=> result) < 0 178 | end 179 | end 180 | } 181 | result 182 | end 183 | 184 | # 15.3.2.2.15 185 | # member?(obj) 186 | alias member? include? 187 | 188 | # 15.3.2.2.16 189 | def partition(&block) 190 | ary_T = [] 191 | ary_F = [] 192 | self.each{|val| 193 | if block.call(val) 194 | ary_T.push(val) 195 | else 196 | ary_F.push(val) 197 | end 198 | } 199 | [ary_T, ary_F] 200 | end 201 | 202 | # 15.3.2.2.17 203 | def reject(&block) 204 | ary = [] 205 | self.each{|val| 206 | ary.push(val) unless block.call(val) 207 | } 208 | ary 209 | end 210 | 211 | # 15.3.2.2.18 212 | # select(&block) 213 | alias select find_all 214 | 215 | 216 | # Does this OK? Please test it. 217 | def __sort_sub__(sorted, work, src_ary, head, tail, &block) 218 | if head == tail 219 | sorted[head] = work[head] if src_ary == 1 220 | return 221 | end 222 | 223 | # on current step, which is a src ary? 224 | if src_ary == 0 225 | src, dst = sorted, work 226 | else 227 | src, dst = work, sorted 228 | end 229 | 230 | key = src[head] # key value for dividing values 231 | i, j = head, tail # position to store on the dst ary 232 | 233 | (head + 1).upto(tail){|idx| 234 | if ((block)? block.call(src[idx], key): (src[idx] <=> key)) > 0 235 | # larger than key 236 | dst[j] = src[idx] 237 | j -= 1 238 | else 239 | dst[i] = src[idx] 240 | i += 1 241 | end 242 | } 243 | 244 | sorted[i] = key 245 | 246 | # sort each sub-array 247 | src_ary = (src_ary + 1) % 2 # exchange a src ary 248 | __sort_sub__(sorted, work, src_ary, head, i - 1, &block) if i > head 249 | __sort_sub__(sorted, work, src_ary, i + 1, tail, &block) if i < tail 250 | end 251 | # private :__sort_sub__ 252 | 253 | # 15.3.2.2.19 254 | def sort(&block) 255 | ary = [] 256 | self.each{|val| ary.push(val)} 257 | unless ary.empty? 258 | __sort_sub__(ary, ::Array.new(ary.size), 0, 0, ary.size - 1, &block) 259 | end 260 | ary 261 | end 262 | 263 | # 15.3.2.2.20 264 | # to_a 265 | alias to_a entries 266 | end 267 | -------------------------------------------------------------------------------- /mrblib/error.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Exception 3 | # 4 | class Exception 5 | # 15.2.22.4.1 6 | def self.exception(*args, &block) 7 | self.new(*args, &block) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /mrblib/hash.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Hash 3 | # 4 | class Hash 5 | # 15.2.13.4.8 6 | def delete(key, &block) 7 | if block && ! self.has_key?(key) 8 | block.call(key) 9 | else 10 | self.__delete(key) 11 | end 12 | end 13 | 14 | # 15.2.13.4.9 15 | def each(&block) 16 | self.keys.each{|k| block.call([k, self[k]])} 17 | self 18 | end 19 | 20 | # 15.2.13.4.10 21 | def each_key(&block) 22 | self.keys.each{|k| block.call(k)} 23 | self 24 | end 25 | 26 | # 15.2.13.4.11 27 | def each_value(&block) 28 | self.keys.each{|k| block.call(self[k])} 29 | self 30 | end 31 | 32 | # 15.2.13.4.16 33 | def initialize(*args, &block) 34 | self.__init_core(block, *args) 35 | end 36 | 37 | # 15.2.13.4.22 38 | def merge(other, &block) 39 | h = {} 40 | raise "can't convert argument into Hash" unless other.respond_to?(:to_hash) 41 | other = other.to_hash 42 | self.each_key{|k| h[k] = self[k]} 43 | if block 44 | other.each_key{|k| 45 | h[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k] 46 | } 47 | else 48 | other.each_key{|k| h[k] = other[k]} 49 | end 50 | h 51 | end 52 | end 53 | 54 | # include modules 55 | module Enumerable; end 56 | class Hash 57 | include Enumerable 58 | end 59 | -------------------------------------------------------------------------------- /mrblib/init_mrblib.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include "irep.h" 3 | #include "dump.h" 4 | #include "mruby/string.h" 5 | #include "mruby/proc.h" 6 | 7 | extern const char mrblib_irep[]; 8 | 9 | void 10 | mrb_init_mrblib(mrb_state *mrb) 11 | { 12 | int n = mrb_read_irep(mrb, mrblib_irep); 13 | 14 | extern mrb_value mrb_top_self(mrb_state *mrb); 15 | mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /mrblib/kernel.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Kernel 3 | # 4 | module Kernel 5 | # 15.3.1.2.6 6 | def self.lambda(&block) 7 | ### *** TODO *** ### 8 | block # dummy 9 | end 10 | 11 | # 15.3.1.2.8 12 | def self.loop #(&block) 13 | while(true) 14 | yield 15 | end 16 | end 17 | 18 | # 15.3.1.3.4 19 | def __send__(symbol, *args, &block) 20 | ### *** TODO *** ### 21 | end 22 | 23 | # 15.3.1.3.18 24 | def instance_eval(string=nil, &block) 25 | ### *** TODO *** ### 26 | end 27 | 28 | # 15.3.1.3.27 29 | def lambda(&block) 30 | ### *** TODO *** ### 31 | block # dummy 32 | end 33 | 34 | # 15.3.1.3.29 35 | def loop #(&block) 36 | while(true) 37 | yield 38 | end 39 | end 40 | 41 | # 15.3.1.3.44 42 | def send(symbol, *args, &block) 43 | ### *** TODO *** ### 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /mrblib/numeric.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Integer 3 | # 4 | class Integer 5 | # 15.2.8.3.15 6 | def downto(num, &block) 7 | raise TypeError, "expected Integer" unless num.kind_of? Integer 8 | i = self 9 | while(i >= num) 10 | block.call(i) 11 | i -= 1 12 | end 13 | self 14 | end 15 | 16 | # 15.2.8.3.22 17 | def times(&block) 18 | i = 0 19 | while(i < self) 20 | block.call(i) 21 | i += 1 22 | end 23 | self 24 | end 25 | 26 | # 15.2.8.3.27 27 | def upto(num, &block) 28 | raise TypeError, "expected Integer" unless num.kind_of? Integer 29 | i = self 30 | while(i <= num) 31 | block.call(i) 32 | i += 1 33 | end 34 | self 35 | end 36 | end 37 | 38 | # include modules 39 | module Comparable; end 40 | class Numeric 41 | include Comparable 42 | end 43 | -------------------------------------------------------------------------------- /mrblib/print.rb: -------------------------------------------------------------------------------- 1 | module Kernel 2 | def print(*args) 3 | i = 0 4 | len = args.size 5 | while i < len 6 | __printstr__ args[i].to_s 7 | i += 1 8 | end 9 | end 10 | def puts(*args) 11 | i = 0 12 | len = args.size 13 | while i < len 14 | __printstr__ args[i].to_s 15 | __printstr__ "\n" 16 | i += 1 17 | end 18 | __printstr__ "\n" if len == 0 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /mrblib/range.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Range 3 | # 4 | class Range 5 | # 15.2.14.4.4 6 | def each(&block) 7 | val = self.first 8 | unless val.respond_to? :succ 9 | raise TypeError, "can't iterate" 10 | end 11 | 12 | last = self.last 13 | return self if (val <=> last) > 0 14 | 15 | while((val <=> last) < 0) 16 | block.call(val) 17 | val = val.succ 18 | end 19 | 20 | block.call(val) unless exclude_end? 21 | 22 | self 23 | end 24 | end 25 | 26 | # include modules 27 | module Enumerable; end 28 | class Range 29 | include Enumerable 30 | end 31 | -------------------------------------------------------------------------------- /mrblib/string.rb: -------------------------------------------------------------------------------- 1 | # 2 | # String 3 | # 4 | class String 5 | # 15.2.10.5.15 6 | def each_line(&block) 7 | # expect that str.index accepts an Integer for 1st argument as a byte data 8 | offset = 0 9 | while(pos = self.index(0x0a, offset)) 10 | block.call(self[offset, pos + 1 - offset]) 11 | offset = pos + 1 12 | end 13 | block.call(self[offset, self.size - offset]) if self.size > offset 14 | self 15 | end 16 | 17 | # 15.2.10.5.18 18 | def gsub(*args, &block) 19 | unless (args.size == 1 && block) || args.size == 2 20 | raise ArgumentError, "wrong number of arguments" 21 | end 22 | 23 | ### *** TODO *** ### 24 | end 25 | 26 | # 15.2.10.5.19 27 | def gsub!(*args, &block) 28 | str = self.gsub(*args, &block) 29 | if str != self 30 | self.replace(str) 31 | self 32 | else 33 | nil 34 | end 35 | end 36 | 37 | # 15.2.10.5.32 38 | def scan(reg, &block) 39 | ### *** TODO *** ### 40 | end 41 | 42 | # 15.2.10.5.36 43 | def sub(*args, &block) 44 | unless (args.size == 1 && block) || args.size == 2 45 | raise ArgumentError, "wrong number of arguments" 46 | end 47 | 48 | ### *** TODO *** ### 49 | end 50 | 51 | # 15.2.10.5.37 52 | def sub!(*args, &block) 53 | str = self.sub(*args, &block) 54 | if str != self 55 | self.replace(str) 56 | self 57 | else 58 | nil 59 | end 60 | end 61 | 62 | def each_char(&block) 63 | pos = 0 64 | while(pos < self.size) 65 | block.call(self[pos]) 66 | pos += 1 67 | end 68 | self 69 | end 70 | 71 | def each_byte(&block) 72 | bytes = self.unpack("C*") 73 | pos = 0 74 | while(pos < bytes.size) 75 | block.call(bytes[pos]) 76 | pos += 1 77 | end 78 | self 79 | end 80 | 81 | def []=(pos, value) 82 | b = self[0, pos] 83 | a = self[pos+1..-1] 84 | p [b, value, a].join('') 85 | self.replace([b, value, a].join('')) 86 | end 87 | end 88 | 89 | # include modules 90 | module Comparable; end 91 | class String 92 | include Comparable 93 | end 94 | -------------------------------------------------------------------------------- /mrblib/struct.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Struct 3 | # 4 | class Struct 5 | # 15.2.18.4.4 6 | def each(&block) 7 | self.class.members.each{|field| 8 | block.call(self[field]) 9 | } 10 | self 11 | end 12 | 13 | # 15.2.18.4.5 14 | def each_pair(&block) 15 | self.class.members.each{|field| 16 | block.call(field.to_sym, self[field]) 17 | } 18 | self 19 | end 20 | 21 | # 15.2.18.4.7 22 | def select(&block) 23 | ary = [] 24 | self.class.members.each{|field| 25 | val = self[field] 26 | ary.push(val) if block.call(val) 27 | } 28 | ary 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | # makefile discription. 2 | # basic build file for RiteVM library 3 | # 11.Apr.2011 coded by Kenji Yoshimoto. 4 | # 31.Aug.2011 coded by Hiroshi Mimaki. 5 | 6 | # project-specific macros 7 | # extension of the executable-file is modifiable(.exe .out ...) 8 | BASEDIR = . 9 | TARGET := ../lib/ritevm 10 | ifeq ($(OS),Windows_NT) 11 | LIB := $(TARGET).lib 12 | else 13 | LIB := $(TARGET).a 14 | endif 15 | YSRC := $(BASEDIR)/parse.y 16 | YC := $(BASEDIR)/y.tab.c 17 | EXCEPT1 := $(YC) $(BASEDIR)/minimain.c $(BASEDIR)/compile.c $(BASEDIR)/dump.c $(BASEDIR)/cdump.c 18 | OBJY := $(patsubst %.c,%.o,$(YC)) 19 | OBJ1 := $(patsubst %.c,%.o,$(filter-out $(EXCEPT1),$(wildcard $(BASEDIR)/*.c))) 20 | #OBJ2 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/regex/*.c)) 21 | #OBJ3 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/enc/*.c)) 22 | OBJS := $(OBJ1) $(OBJ2) $(OBJ3) 23 | # mruby libraries 24 | EXTC := $(BASEDIR)/../mrblib/mrblib.c 25 | EXTRB := $(wildcard $(BASEDIR)/../mrblib/*.rb) 26 | EXTM := $(patsubst %.c,%.o,$(EXTC)) 27 | # extend libraries 28 | #EXT1 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/socket/*.c)) 29 | EXTS := $(EXT1) 30 | 31 | # libraries, includes 32 | INCLUDES = -I$(BASEDIR) -I$(BASEDIR)/../include 33 | #INCLUDES = -I$(RITEVM_ROOT) 34 | 35 | # compiler, linker (gcc) 36 | CC = gcc 37 | LL = gcc 38 | AR = ar 39 | YACC = bison 40 | 41 | DEBUG_MODE = 1 42 | ifeq ($(DEBUG_MODE),1) 43 | CFLAGS = -g 44 | else 45 | CFLAGS = -O3 46 | endif 47 | ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS) 48 | MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL) 49 | 50 | ############################## 51 | # generic build targets, rules 52 | 53 | .PHONY : all 54 | all : $(EXTM) $(LIB) 55 | @echo "make: built targets of `pwd`" 56 | 57 | # executable constructed using linker from object files 58 | $(LIB) : $(OBJS) $(OBJY) $(EXTM) $(EXTS) 59 | $(AR) r $@ $(OBJS) $(OBJY) $(EXTM) $(EXTS) 60 | 61 | -include $(OBJS:.o=.d) $(OBJY:.o=.d) 62 | 63 | # objects compiled from source 64 | $(OBJS) : %.o : %.c 65 | $(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@ 66 | 67 | # mruby library compile 68 | $(EXTM) : $(EXTRB) $(OBJS) $(OBJY) 69 | $(MAKE) -C ../mrblib $(MAKE_FLAGS) 70 | 71 | # extend libraries complile 72 | $(EXTS) : %.o : %.c 73 | $(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@ 74 | 75 | # parser complie 76 | $(OBJY) : $(YC) 77 | $(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $(YC) -o $(OBJY) 78 | 79 | # yacc complie 80 | $(YC) : $(YSRC) 81 | $(YACC) -o $(YC) $(YSRC) 82 | 83 | # clean up 84 | .PHONY : clean #cleandep 85 | clean : 86 | $(MAKE) clean -C ../mrblib $(MAKE_FLAGS) 87 | -rm -f $(LIB) $(OBJS) $(OBJY) $(YC) 88 | -rm -f $(OBJS:.o=.d) $(OBJY:.o=.d) 89 | @echo "make: removing targets, objects and depend files of `pwd`" 90 | 91 | -------------------------------------------------------------------------------- /src/ascii.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | ascii.c - Oniguruma (regular expression library) 3 | **********************************************************************/ 4 | /*- 5 | * Copyright (c) 2002-2006 K.Kosako 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #include "mruby.h" 31 | #ifdef INCLUDE_ENCODING 32 | #include "regenc.h" 33 | 34 | OnigEncodingDefine(ascii, ASCII) = { 35 | onigenc_single_byte_mbc_enc_len, 36 | "ASCII-8BIT",/* name */ 37 | 1, /* max byte length */ 38 | 1, /* min byte length */ 39 | onigenc_is_mbc_newline_0x0a, 40 | onigenc_single_byte_mbc_to_code, 41 | onigenc_single_byte_code_to_mbclen, 42 | onigenc_single_byte_code_to_mbc, 43 | onigenc_ascii_mbc_case_fold, 44 | onigenc_ascii_apply_all_case_fold, 45 | onigenc_ascii_get_case_fold_codes_by_str, 46 | onigenc_minimum_property_name_to_ctype, 47 | onigenc_ascii_is_code_ctype, 48 | onigenc_not_support_get_ctype_code_range, 49 | onigenc_single_byte_left_adjust_char_head, 50 | onigenc_always_true_is_allowed_reverse_match 51 | }; 52 | ENC_ALIAS("BINARY", "ASCII-8BIT") 53 | ENC_REPLICATE("IBM437", "ASCII-8BIT") 54 | ENC_ALIAS("CP437", "IBM437") 55 | ENC_REPLICATE("IBM737", "ASCII-8BIT") 56 | ENC_ALIAS("CP737", "IBM737") 57 | ENC_REPLICATE("IBM775", "ASCII-8BIT") 58 | ENC_ALIAS("CP775", "IBM775") 59 | ENC_REPLICATE("CP850", "ASCII-8BIT") 60 | ENC_ALIAS("IBM850", "CP850") 61 | ENC_REPLICATE("IBM852", "ASCII-8BIT") 62 | ENC_REPLICATE("CP852", "IBM852") 63 | ENC_REPLICATE("IBM855", "ASCII-8BIT") 64 | ENC_REPLICATE("CP855", "IBM855") 65 | ENC_REPLICATE("IBM857", "ASCII-8BIT") 66 | ENC_ALIAS("CP857", "IBM857") 67 | ENC_REPLICATE("IBM860", "ASCII-8BIT") 68 | ENC_ALIAS("CP860", "IBM860") 69 | ENC_REPLICATE("IBM861", "ASCII-8BIT") 70 | ENC_ALIAS("CP861", "IBM861") 71 | ENC_REPLICATE("IBM862", "ASCII-8BIT") 72 | ENC_ALIAS("CP862", "IBM862") 73 | ENC_REPLICATE("IBM863", "ASCII-8BIT") 74 | ENC_ALIAS("CP863", "IBM863") 75 | ENC_REPLICATE("IBM864", "ASCII-8BIT") 76 | ENC_ALIAS("CP864", "IBM864") 77 | ENC_REPLICATE("IBM865", "ASCII-8BIT") 78 | ENC_ALIAS("CP865", "IBM865") 79 | ENC_REPLICATE("IBM866", "ASCII-8BIT") 80 | ENC_ALIAS("CP866", "IBM866") 81 | ENC_REPLICATE("IBM869", "ASCII-8BIT") 82 | ENC_ALIAS("CP869", "IBM869") 83 | ENC_REPLICATE("Windows-1258", "ASCII-8BIT") 84 | ENC_ALIAS("CP1258", "Windows-1258") 85 | ENC_REPLICATE("GB1988", "ASCII-8BIT") 86 | ENC_REPLICATE("macCentEuro", "ASCII-8BIT") 87 | ENC_REPLICATE("macCroatian", "ASCII-8BIT") 88 | ENC_REPLICATE("macCyrillic", "ASCII-8BIT") 89 | ENC_REPLICATE("macGreek", "ASCII-8BIT") 90 | ENC_REPLICATE("macIceland", "ASCII-8BIT") 91 | ENC_REPLICATE("macRoman", "ASCII-8BIT") 92 | ENC_REPLICATE("macRomania", "ASCII-8BIT") 93 | ENC_REPLICATE("macThai", "ASCII-8BIT") 94 | ENC_REPLICATE("macTurkish", "ASCII-8BIT") 95 | ENC_REPLICATE("macUkraine", "ASCII-8BIT") 96 | #endif //INCLUDE_ENCODING 97 | -------------------------------------------------------------------------------- /src/cdump.c: -------------------------------------------------------------------------------- 1 | #include "cdump.h" 2 | 3 | #include 4 | 5 | #include "irep.h" 6 | #include "mruby/string.h" 7 | #include "re.h" 8 | 9 | #define MRB_CDUMP_LINE_LEN 128 10 | 11 | #define SOURCE_CODE(fmt, ...) fprintf(f, fmt"\n", __VA_ARGS__) 12 | #define SOURCE_CODE0(str) do {fputs(str, f); putc('\n', f);} while (0) 13 | 14 | static int 15 | make_cdump_isec(mrb_state *mrb, int irep_no, FILE *f) 16 | { 17 | int i; 18 | mrb_irep *irep = mrb->irep[irep_no]; 19 | 20 | if (irep == 0) 21 | return -1; 22 | 23 | /* dump isec struct*/ 24 | if (irep->ilen > 0) { 25 | SOURCE_CODE ("static mrb_code iseq_%d[] = {", irep_no); 26 | for (i=0; iilen; i++) 27 | SOURCE_CODE(" 0x%08x," , irep->iseq[i]); 28 | SOURCE_CODE0 ("};"); 29 | SOURCE_CODE0 (""); 30 | } 31 | 32 | return 0; 33 | } 34 | 35 | static size_t 36 | str_format_len(mrb_value str) 37 | { 38 | size_t dump_len = 0; 39 | 40 | char *src; 41 | 42 | for (src = RSTRING_PTR(str); src < RSTRING_END(str);) { 43 | switch (*src) { 44 | case 0x07:/* BEL */ /* fall through */ 45 | case 0x08:/* BS */ /* fall through */ 46 | case 0x09:/* HT */ /* fall through */ 47 | case 0x0A:/* LF */ /* fall through */ 48 | case 0x0B:/* VT */ /* fall through */ 49 | case 0x0C:/* FF */ /* fall through */ 50 | case 0x0D:/* CR */ /* fall through */ 51 | case 0x22:/* " */ /* fall through */ 52 | case 0x27:/* ' */ /* fall through */ 53 | case 0x3F:/* ? */ /* fall through */ 54 | case 0x5C:/* \ */ /* fall through */ 55 | dump_len += 2; src += 2; 56 | break; 57 | 58 | default: 59 | dump_len++; src++; 60 | break; 61 | } 62 | } 63 | 64 | return dump_len; 65 | } 66 | 67 | static char* 68 | str_to_format(mrb_value str, char *buf) 69 | { 70 | char *src, *dst; 71 | 72 | for (src = RSTRING_PTR(str), dst = buf; src < RSTRING_END(str);) { 73 | switch (*src) { 74 | case 0x07:/* BEL */ memcpy(dst, "\\a", 2); dst+=2; src+=2; break; 75 | case 0x08:/* BS */ memcpy(dst, "\\b", 2); dst+=2; src+=2; break; 76 | case 0x09:/* HT */ memcpy(dst, "\\t", 2); dst+=2; src+=2; break; 77 | case 0x0A:/* LF */ memcpy(dst, "\\n", 2); dst+=2; src+=2; break; 78 | case 0x0B:/* VT */ memcpy(dst, "\\v", 2); dst+=2; src+=2; break; 79 | case 0x0C:/* FF */ memcpy(dst, "\\f", 2); dst+=2; src+=2; break; 80 | case 0x0D:/* CR */ memcpy(dst, "\\r", 2); dst+=2; src+=2; break; 81 | case 0x22:/* " */ memcpy(dst, "\\\"", 2); dst+=2; src+=2; break; 82 | case 0x27:/* ' */ memcpy(dst, "\\\'", 2); dst+=2; src+=2; break; 83 | case 0x3F:/* ? */ memcpy(dst, "\\\?", 2); dst+=2; src+=2; break; 84 | case 0x5C:/* \ */ memcpy(dst, "\\\\", 2); dst+=2; src+=2; break; 85 | default: *dst++ = *src++; break; 86 | } 87 | } 88 | 89 | return buf; 90 | } 91 | 92 | int 93 | make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f) 94 | { 95 | mrb_irep *irep = mrb->irep[irep_no]; 96 | int n; 97 | char *buf = 0; 98 | size_t buf_len, str_len; 99 | 100 | if (irep == 0) 101 | return -1; 102 | 103 | buf_len = MRB_CDUMP_LINE_LEN; 104 | if ((buf = mrb_malloc(mrb, buf_len)) == 0 ) { 105 | return MRB_CDUMP_GENERAL_FAILURE; 106 | } 107 | 108 | SOURCE_CODE0 (" irep = mrb->irep[idx] = mrb_malloc(mrb, sizeof(mrb_irep));"); 109 | SOURCE_CODE0 (" irep->idx = idx++;"); 110 | SOURCE_CODE (" irep->flags = %d | MRB_ISEQ_NOFREE;", irep->flags); 111 | SOURCE_CODE (" irep->nlocals = %d;", irep->nlocals); 112 | SOURCE_CODE (" irep->nregs = %d;", irep->nregs); 113 | SOURCE_CODE (" irep->ilen = %d;", irep->ilen); 114 | SOURCE_CODE (" irep->iseq = iseq_%d;", irep_no); 115 | 116 | SOURCE_CODE (" irep->slen = %d;", irep->slen); 117 | if(irep->slen > 0) { 118 | SOURCE_CODE (" irep->syms = mrb_malloc(mrb, sizeof(mrb_sym)*%d);", irep->slen); 119 | for (n=0; nslen; n++) 120 | if (irep->syms[n]) { 121 | SOURCE_CODE (" irep->syms[%d] = mrb_intern(mrb, \"%s\");", n, mrb_sym2name(mrb, irep->syms[n])); 122 | } 123 | } 124 | else 125 | SOURCE_CODE0 (" irep->syms = NULL;"); 126 | 127 | SOURCE_CODE (" irep->plen = %d;", irep->plen); 128 | if(irep->plen > 0) { 129 | SOURCE_CODE (" irep->pool = mrb_malloc(mrb, sizeof(mrb_value)*%d);", irep->plen); 130 | for (n=0; nplen; n++) { 131 | switch (irep->pool[n].tt) { 132 | case MRB_TT_FLOAT: 133 | SOURCE_CODE(" irep->pool[%d] = mrb_float_value(%.16e);", n, irep->pool[n].value.f); break; 134 | case MRB_TT_STRING: 135 | str_len = str_format_len(irep->pool[n]) + 1; 136 | if ( str_len > buf_len ) { 137 | buf_len = str_len; 138 | if ((buf = mrb_realloc(mrb, buf, buf_len)) == 0 ) { 139 | return MRB_CDUMP_GENERAL_FAILURE; 140 | } 141 | } 142 | memset(buf, 0, buf_len); 143 | SOURCE_CODE(" irep->pool[%d] = mrb_str_new(mrb, \"%s\", %d);", n, str_to_format(irep->pool[n], buf), RSTRING_LEN(irep->pool[n])); break; 144 | /* TODO MRB_TT_REGEX */ 145 | default: break; 146 | } 147 | } 148 | } 149 | else 150 | SOURCE_CODE0 (" irep->pool = NULL;"); 151 | SOURCE_CODE0(""); 152 | return MRB_CDUMP_OK; 153 | } 154 | 155 | int 156 | mrb_cdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname) 157 | { 158 | int irep_no, irep_num; 159 | 160 | if (mrb == 0 || n < 0 || n >= mrb->irep_len || f == 0 || initname == 0) 161 | return -1; 162 | 163 | irep_num = mrb->irep_len - n; 164 | 165 | SOURCE_CODE0("#include \"mruby.h\""); 166 | SOURCE_CODE0("#include \"irep.h\""); 167 | SOURCE_CODE0("#include \"mruby/string.h\""); 168 | SOURCE_CODE0("#include \"mruby/proc.h\""); 169 | SOURCE_CODE0(""); 170 | 171 | for (irep_no=n; irep_noirep_len; irep_no++) { 172 | if (make_cdump_isec(mrb, irep_no, f) != 0) 173 | return -1; 174 | } 175 | 176 | SOURCE_CODE0("void"); 177 | SOURCE_CODE ("%s(mrb_state *mrb)", initname); 178 | SOURCE_CODE0("{"); 179 | SOURCE_CODE0(" int n = mrb->irep_len;"); 180 | SOURCE_CODE0(" int idx = n;"); 181 | SOURCE_CODE0(" mrb_irep *irep;"); 182 | SOURCE_CODE0(""); 183 | SOURCE_CODE (" mrb_add_irep(mrb, idx+%d);", irep_num); 184 | SOURCE_CODE0(""); 185 | for (irep_no=n; irep_noirep_len; irep_no++) { 186 | if (make_cdump_irep(mrb, irep_no, f) != 0) 187 | return -1; 188 | } 189 | 190 | SOURCE_CODE0(" mrb->irep_len = idx;"); 191 | SOURCE_CODE0(""); 192 | SOURCE_CODE0(" extern mrb_value mrb_top_self(mrb_state *mrb);"); 193 | SOURCE_CODE0(" mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));"); 194 | SOURCE_CODE0("}"); 195 | 196 | return 0; 197 | } 198 | -------------------------------------------------------------------------------- /src/cdump.h: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include 3 | 4 | int mrb_cdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname); 5 | 6 | /* error code */ 7 | #define MRB_CDUMP_OK 0 8 | #define MRB_CDUMP_GENERAL_FAILURE -1 9 | -------------------------------------------------------------------------------- /src/compar.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include "mruby/string.h" 3 | #include "mruby/numeric.h" 4 | 5 | void 6 | mrb_cmperr(mrb_state *mrb, mrb_value x, mrb_value y) 7 | { 8 | const char *classname; 9 | 10 | if (SPECIAL_CONST_P(y)) { 11 | y = mrb_inspect(mrb, y); 12 | //classname = StringValuePtr(y); 13 | classname = mrb_string_value_ptr(mrb, y); 14 | } 15 | else { 16 | classname = mrb_obj_classname(mrb, y); 17 | } 18 | mrb_raise(mrb, E_ARGUMENT_ERROR, "comparison of %s with %s failed", 19 | mrb_obj_classname(mrb, x), classname); 20 | } 21 | 22 | int 23 | mrb_cmpint(mrb_state *mrb, mrb_value val, mrb_value a, mrb_value b) 24 | { 25 | if (mrb_nil_p(val)) { 26 | mrb_cmperr(mrb, a, b); 27 | } 28 | if (FIXNUM_P(val)) { 29 | long l = mrb_fixnum(val); 30 | if (l > 0) return 1; 31 | if (l < 0) return -1; 32 | return 0; 33 | } 34 | if (mrb_test(mrb_funcall(mrb, val, ">", 1, mrb_fixnum_value(0)))) return 1; 35 | if (mrb_test(mrb_funcall(mrb, val, "<", 1, mrb_fixnum_value(0)))) return -1; 36 | return 0; 37 | } 38 | 39 | static mrb_value 40 | cmp_equal(mrb_state *mrb, mrb_value x) 41 | { 42 | mrb_value y, c; 43 | 44 | /* *** TEMPORAL IMPLEMENT *** */ 45 | 46 | mrb_get_args(mrb, "o", &y); 47 | if (mrb_obj_equal(mrb, x, y)) return mrb_true_value(); 48 | 49 | c = mrb_funcall(mrb, x, "<=>", 1, y); 50 | 51 | if (mrb_cmpint(mrb, c, x, y) == 0) return mrb_true_value(); 52 | return mrb_false_value(); 53 | } 54 | 55 | #include 56 | static mrb_value 57 | cmp_gt(mrb_state *mrb, mrb_value x, mrb_value y) 58 | { 59 | mrb_value c; 60 | 61 | c = mrb_funcall(mrb, x, "<=>", 1, y); 62 | 63 | if (mrb_cmpint(mrb, c, x, y) > 0) return mrb_true_value(); 64 | return mrb_false_value(); 65 | } 66 | 67 | static mrb_value 68 | cmp_gt_m(mrb_state *mrb, mrb_value x) 69 | { 70 | mrb_value y; 71 | 72 | mrb_get_args(mrb, "o", &y); 73 | return cmp_gt(mrb, x, y); 74 | } 75 | 76 | static mrb_value 77 | cmp_ge_m(mrb_state *mrb, mrb_value x) 78 | { 79 | mrb_value y, c; 80 | 81 | mrb_get_args(mrb, "o", &y); 82 | c = mrb_funcall(mrb, x, "<=>", 1, y); 83 | 84 | if (mrb_cmpint(mrb, c, x, y) >= 0) return mrb_true_value(); 85 | return mrb_false_value(); 86 | } 87 | 88 | static mrb_value 89 | cmp_lt(mrb_state *mrb, mrb_value x, mrb_value y) 90 | { 91 | mrb_value c; 92 | 93 | c = mrb_funcall(mrb, x, "<=>", 1, y); 94 | 95 | if (mrb_cmpint(mrb, c, x, y) < 0) return mrb_true_value(); 96 | return mrb_false_value(); 97 | } 98 | 99 | static mrb_value 100 | cmp_lt_m(mrb_state *mrb, mrb_value x) 101 | { 102 | mrb_value y; 103 | 104 | mrb_get_args(mrb, "o", &y); 105 | return cmp_lt(mrb, x, y); 106 | } 107 | 108 | static mrb_value 109 | cmp_le_m(mrb_state *mrb, mrb_value x) 110 | { 111 | mrb_value y, c; 112 | 113 | mrb_get_args(mrb, "o", &y); 114 | c = mrb_funcall(mrb, x, "<=>", 1, y); 115 | 116 | if (mrb_cmpint(mrb, c, x, y) <= 0) return mrb_true_value(); 117 | return mrb_false_value(); 118 | } 119 | 120 | static mrb_value 121 | cmp_between(mrb_state *mrb, mrb_value x) 122 | { 123 | mrb_value min, max; 124 | 125 | mrb_get_args(mrb, "oo", &min, &max); 126 | 127 | if (mrb_test(cmp_lt(mrb, x, min))) return mrb_false_value(); 128 | if (mrb_test(cmp_gt(mrb, x, max))) return mrb_false_value(); 129 | return mrb_true_value(); 130 | } 131 | 132 | void 133 | mrb_init_comparable(mrb_state *mrb) 134 | { 135 | struct RClass *comp; 136 | 137 | comp = mrb_define_module(mrb, "Comparable"); 138 | mrb_define_method(mrb, comp, "<", cmp_lt_m, ARGS_REQ(1)); /* 15.3.3.2.1 */ 139 | mrb_define_method(mrb, comp, "<=", cmp_le_m, ARGS_REQ(1)); /* 15.3.3.2.2 */ 140 | mrb_define_method(mrb, comp, "==", cmp_equal, ARGS_REQ(1)); /* 15.3.3.2.3 */ 141 | mrb_define_method(mrb, comp, ">", cmp_gt_m, ARGS_REQ(1)); /* 15.3.3.2.4 */ 142 | mrb_define_method(mrb, comp, ">=", cmp_ge_m, ARGS_REQ(1)); /* 15.3.3.2.5 */ 143 | mrb_define_method(mrb, comp, "between?", cmp_between, ARGS_REQ(2)); /* 15.3.3.2.6 */ 144 | } 145 | -------------------------------------------------------------------------------- /src/compile.h: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include 3 | #include 4 | 5 | typedef struct mrb_ast_node { 6 | struct mrb_ast_node *car, *cdr; 7 | } mrb_ast_node; 8 | 9 | #include "node.h" 10 | #include "pool.h" 11 | #include 12 | 13 | enum mrb_lex_state_enum { 14 | EXPR_BEG, /* ignore newline, +/- is a sign. */ 15 | EXPR_END, /* newline significant, +/- is an operator. */ 16 | EXPR_ENDARG, /* ditto, and unbound braces. */ 17 | EXPR_ENDFN, /* ditto, and unbound braces. */ 18 | EXPR_ARG, /* newline significant, +/- is an operator. */ 19 | EXPR_CMDARG, /* newline significant, +/- is an operator. */ 20 | EXPR_MID, /* newline significant, +/- is an operator. */ 21 | EXPR_FNAME, /* ignore newline, no reserved words. */ 22 | EXPR_DOT, /* right after `.' or `::', no reserved words. */ 23 | EXPR_CLASS, /* immediate after `class', no here document. */ 24 | EXPR_VALUE, /* alike EXPR_BEG but label is disallowed. */ 25 | EXPR_MAX_STATE 26 | }; 27 | 28 | struct mrb_parser_state { 29 | mrb_state *mrb; 30 | struct mrb_pool *pool; 31 | mrb_ast_node *cells; 32 | char *s, *send; 33 | FILE *f; 34 | int lineno; 35 | int column; 36 | const char *filename; 37 | 38 | enum mrb_lex_state_enum lstate; 39 | int sterm; 40 | 41 | unsigned int cond_stack; 42 | unsigned int cmdarg_stack; 43 | int paren_nest; 44 | int lpar_beg; 45 | 46 | mrb_ast_node *pb; 47 | char buf[1024]; 48 | int bidx; 49 | 50 | mrb_ast_node *heredoc; 51 | 52 | int in_def, in_single, cmd_start; 53 | mrb_ast_node *locals; 54 | 55 | void *ylval; 56 | 57 | int nerr; 58 | mrb_ast_node *tree, *begin_tree; 59 | 60 | jmp_buf jmp; 61 | }; 62 | 63 | struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*); 64 | struct mrb_parser_state* mrb_parse_string(mrb_state*,char*); 65 | struct mrb_parser_state* mrb_parse_nstring(mrb_state*,char*,size_t); 66 | int mrb_generate_code(mrb_state*, mrb_ast_node*); 67 | 68 | int mrb_compile_file(mrb_state*,FILE*); 69 | int mrb_compile_string(mrb_state*,char*); 70 | int mrb_compile_nstring(mrb_state*,char*,size_t); 71 | 72 | const char *mrb_parser_filename(struct mrb_parser_state *p, const char *s); 73 | int mrb_parser_lineno(struct mrb_parser_state *p, int n); 74 | -------------------------------------------------------------------------------- /src/crc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | // Calculate CRC (CRC-16-CCITT) 4 | // 5 | // 0000_0000_0000_0000_0000_0000_0000_0000 6 | // ^|------- CRC -------|- work --| 7 | // carry 8 | #define CRC_16_CCITT 0x11021ul //x^16+x^12+x^5+1 9 | #define CRC_XOR_PATTERN (CRC_16_CCITT << 8) 10 | #define CRC_CARRY_BIT (1 << 24) 11 | 12 | uint16_t 13 | calc_crc_16_ccitt(unsigned char *src, int nbytes) 14 | { 15 | uint32_t crcwk = 0ul; 16 | int ibyte, ibit; 17 | 18 | for (ibyte = 0; ibyte < nbytes; ibyte++) { 19 | crcwk |= *src++; 20 | for (ibit = 0; ibit < CHAR_BIT; ibit++) { 21 | crcwk <<= 1; 22 | if (crcwk & CRC_CARRY_BIT) { 23 | crcwk ^= CRC_XOR_PATTERN; 24 | } 25 | } 26 | } 27 | return (uint16_t)(crcwk >> 8); 28 | } 29 | -------------------------------------------------------------------------------- /src/dump.h: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include 3 | #include 4 | 5 | int mrb_dump_irep(mrb_state*,int,FILE*); 6 | int mrb_load_irep(mrb_state*,FILE*); 7 | int mrb_load_irep_offset(mrb_state*,FILE*,long); 8 | int mrb_read_irep(mrb_state*,char*); 9 | 10 | int mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname); 11 | 12 | /* dump type */ 13 | #define DUMP_TYPE_CODE 0 14 | #define DUMP_TYPE_BIN 1 15 | #define DUMP_TYPE_HEX 2 16 | 17 | /* dump/load error code */ 18 | #define MRB_DUMP_OK 0 19 | #define MRB_DUMP_GENERAL_FAILURE -1 20 | #define MRB_DUMP_WRITE_FAULT -2 21 | #define MRB_DUMP_READ_FAULT -3 22 | #define MRB_DUMP_CRC_ERROR -4 23 | #define MRB_DUMP_INVALID_FILE_HEADER -5 24 | #define MRB_DUMP_INVALID_IREP -6 25 | #define MRB_DUMP_INVALID_ARGUMENT -7 26 | 27 | /* size of long/int/short value on dump/load */ 28 | #define MRB_DUMP_SIZE_OF_LONG 4 29 | #define MRB_DUMP_SIZE_OF_INT 4 30 | #define MRB_DUMP_SIZE_OF_SHORT 2 31 | 32 | /* null symbol length */ 33 | #define MRB_DUMP_NULL_SYM_LEN 0xFFFF 34 | 35 | /* Use HEX format string */ 36 | #define RITE_FILE_IS_HEX 37 | 38 | #ifdef RITE_FILE_IS_HEX 39 | #define RITE_FILE_HEX_SIZE 2 40 | #else 41 | #define RITE_FILE_HEX_SIZE 1 42 | #endif 43 | 44 | /* Rite Binary File header */ 45 | #define RITE_FILE_IDENFIFIER "RITE" 46 | #define RITE_FILE_FORMAT_VER "00090000" 47 | #define RITE_VM_VER "00090000" 48 | #define RITE_COMPILER_TYPE "MATZ " 49 | #define RITE_COMPILER_VER "00090000" 50 | #define RITE_RESERVED " " 51 | 52 | /* irep header */ 53 | #define RITE_IREP_IDENFIFIER 'S' 54 | #define RITE_IREP_TYPE_CLASS 'C' 55 | #define RITE_IREP_TYPE_MODULE 'M' 56 | 57 | #define MRB_DUMP_DEFAULT_STR_LEN 128 58 | 59 | //Rite Binary file_header 60 | typedef struct _rite_binary_header { 61 | unsigned char rbfi[4]; //Rite Binary File Identify 62 | unsigned char rbfv[8]; //Rite Binary File Format Version 63 | unsigned char risv[8]; //Rite Instruction Specification Version 64 | unsigned char rct[8]; //Rite Compiler Type 65 | unsigned char rcv[8]; //Rite Compiler Version 66 | unsigned char rbds[4]; //Rite Binary Data Size 67 | unsigned char nirep[2]; //Number of ireps 68 | unsigned char sirep[2]; //Start index 69 | unsigned char rsv[8]; //Reserved 70 | } rite_binary_header; 71 | 72 | // Rite File file_header 73 | typedef struct _rite_file_header { 74 | unsigned char rbfi[4]; //Rite Binary File Identify 75 | unsigned char rbfv[8]; //Rite Binary File Format Version 76 | unsigned char risv[8]; //Rite Instruction Specification Version 77 | unsigned char rct[8]; //Rite Compiler Type 78 | unsigned char rcv[8]; //Rite Compiler Version 79 | unsigned char rbds[8]; //Rite Binary Data Size 80 | unsigned char nirep[4]; //Number of ireps 81 | unsigned char sirep[4]; //Start index 82 | unsigned char rsv[8]; //Reserved 83 | unsigned char hcrc[4]; //HCRC 84 | } rite_file_header; 85 | 86 | static inline int 87 | uint16_to_bin(uint16_t s, char *bin) 88 | { 89 | *bin++ = (s >> 8) & 0xff; 90 | *bin = s & 0xff; 91 | return (MRB_DUMP_SIZE_OF_SHORT); 92 | } 93 | 94 | static inline int 95 | uint32_to_bin(uint32_t l, char *bin) 96 | { 97 | *bin++ = (l >> 24) & 0xff; 98 | *bin++ = (l >> 16) & 0xff; 99 | *bin++ = (l >> 8) & 0xff; 100 | *bin = l & 0xff; 101 | return (MRB_DUMP_SIZE_OF_LONG); 102 | } 103 | 104 | static inline uint32_t 105 | bin_to_uint32(unsigned char bin[]) 106 | { 107 | return (uint32_t)bin[0] << 24 | 108 | (uint32_t)bin[1] << 16 | 109 | (uint32_t)bin[2] << 8 | 110 | (uint32_t)bin[3]; 111 | } 112 | 113 | static inline uint16_t 114 | bin_to_uint16(unsigned char bin[]) 115 | { 116 | return (uint16_t)bin[0] << 8 | 117 | (uint16_t)bin[1]; 118 | } 119 | -------------------------------------------------------------------------------- /src/error.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_ERROR_H 2 | #define MRUBY_ERROR_H 3 | 4 | struct RException { 5 | MRUBY_OBJECT_HEADER; 6 | }; 7 | 8 | void mrb_sys_fail(mrb_state *mrb, const char *mesg); 9 | void mrb_exc_raise(mrb_state *mrb, mrb_value mesg); 10 | void mrb_bug_errno(const char*, int); 11 | int sysexit_status(mrb_state *mrb, mrb_value err); 12 | void error_pos(void); 13 | mrb_value mrb_exc_new3(mrb_state *mrb, struct RClass* c, mrb_value str); 14 | mrb_value make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr); 15 | mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len); 16 | mrb_value mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv); 17 | mrb_value mrb_sprintf(mrb_state *mrb, const char *fmt, ...); 18 | void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...); 19 | void mrb_exc_print(mrb_state *mrb, struct RObject *exc); 20 | 21 | #endif /* MRUBY_ERROR_H */ 22 | -------------------------------------------------------------------------------- /src/etc.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include "mdata.h" 3 | #include "mruby/string.h" 4 | #include "error.h" 5 | #include "mruby/numeric.h" 6 | 7 | #ifndef FALSE 8 | #define FALSE 0 9 | #endif 10 | 11 | #ifndef TRUE 12 | #define TRUE 1 13 | #endif 14 | 15 | void 16 | ruby_xfree(void *x) 17 | { 18 | //if (x) 19 | // vm_xfree(&mrb_objspace, x); 20 | } 21 | 22 | struct RData* 23 | mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const struct mrb_data_type *type) 24 | { 25 | struct RData *data; 26 | 27 | data = mrb_obj_alloc(mrb, MRB_TT_DATA, klass); 28 | data->data = ptr; 29 | data->type = type; 30 | 31 | return data; 32 | } 33 | 34 | void * 35 | mrb_check_datatype(mrb_state *mrb, mrb_value obj, const struct mrb_data_type *type) 36 | { 37 | static const char mesg[] = "wrong argument type %s (expected %s)"; 38 | 39 | if (SPECIAL_CONST_P(obj) || (mrb_type(obj) != MRB_TT_DATA)) { 40 | mrb_check_type(mrb, obj, MRB_TT_DATA); 41 | } 42 | if (DATA_TYPE(obj) != type) { 43 | const char *etype = DATA_TYPE(obj)->struct_name; 44 | mrb_raise(mrb, E_TYPE_ERROR, mesg, etype, type->struct_name); 45 | } 46 | return DATA_PTR(obj); 47 | } 48 | 49 | mrb_value 50 | mrb_lastline_get(mrb_state *mrb) 51 | { 52 | //mrb_value *var = mrb_svar(0); 53 | //if (var) { 54 | // return *var; 55 | //} 56 | //return mrb_nil_value(); 57 | mrb_value *argv; 58 | int argc; 59 | mrb_get_args(mrb, "*", &argv, &argc); 60 | if (argc < 1) { 61 | return mrb_nil_value(); 62 | } 63 | else 64 | { 65 | return argv[0]; 66 | } 67 | } 68 | 69 | mrb_value 70 | mrb_rescue2(mrb_state *mrb, mrb_value (* b_proc) (ANYARGS), mrb_value *data1, 71 | mrb_value (* r_proc) (ANYARGS), mrb_value *data2, ...) 72 | { 73 | mrb_value result = (*b_proc) (mrb, data1); 74 | return result; 75 | } 76 | 77 | mrb_value 78 | mrb_rescue(mrb_state *mrb, mrb_value (* b_proc)(ANYARGS), mrb_value *data1, 79 | mrb_value (* r_proc)(ANYARGS), mrb_value *data2) 80 | { 81 | return mrb_rescue2(mrb, b_proc, data1, r_proc, data2, mrb->eStandardError_class, 82 | mrb_fixnum_value(0)); 83 | } 84 | /* ------------------------------------------------ */ 85 | /* 86 | * Calls func(obj, arg, recursive), where recursive is non-zero if the 87 | * current method is called recursively on obj 88 | */ 89 | 90 | mrb_value 91 | mrb_exec_recursive(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int), mrb_value obj, void *arg) 92 | { 93 | // return mrb_exec_recursive(mrb, io_puts_ary, line, &out); 94 | return func(mrb, obj, *(mrb_value*)arg, 0); 95 | } 96 | 97 | /* 98 | * Calls func(obj, arg, recursive), where recursive is non-zero if the 99 | * current method is called recursively on the ordered pair 100 | */ 101 | 102 | mrb_value 103 | mrb_exec_recursive_paired(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int), 104 | mrb_value obj, mrb_value paired_obj, void* arg) 105 | { 106 | // return mrb_exec_recursive_paired(mrb, recursive_eql, hash1, hash2, mrb_fixnum_value((int)&data)); 107 | return func(mrb, obj, paired_obj, 0); 108 | } 109 | 110 | mrb_sym 111 | mrb_to_id(mrb_state *mrb, mrb_value name) 112 | { 113 | mrb_value tmp; 114 | mrb_sym id; 115 | 116 | switch (mrb_type(name)) { 117 | default: 118 | tmp = mrb_check_string_type(mrb, name); 119 | if (mrb_nil_p(tmp)) { 120 | tmp = mrb_inspect(mrb, name); 121 | mrb_raise(mrb, E_TYPE_ERROR, "%s is not a symbol", 122 | RSTRING_PTR(tmp)); 123 | } 124 | name = tmp; 125 | /* fall through */ 126 | case MRB_TT_STRING: 127 | name = mrb_str_intern(mrb, name); 128 | /* fall through */ 129 | case MRB_TT_SYMBOL: 130 | return SYM2ID(name); 131 | } 132 | return id; 133 | } 134 | 135 | /* 136 | * call-seq: 137 | * proc { |...| block } -> a_proc 138 | * 139 | * Equivalent to Proc.new. 140 | */ 141 | 142 | mrb_value 143 | mrb_block_proc(void) 144 | { 145 | return mrb_nil_value();//proc_new(mrb_cProc, FALSE); 146 | } 147 | 148 | /* 149 | * Document-method: __id__ 150 | * Document-method: object_id 151 | * 152 | * call-seq: 153 | * obj.__id__ -> fixnum 154 | * obj.object_id -> fixnum 155 | * 156 | * Returns an integer identifier for obj. The same number will 157 | * be returned on all calls to id for a given object, and 158 | * no two active objects will share an id. 159 | * Object#object_id is a different concept from the 160 | * :name notation, which returns the symbol id of 161 | * name. Replaces the deprecated Object#id. 162 | */ 163 | 164 | /* 165 | * call-seq: 166 | * obj.hash -> fixnum 167 | * 168 | * Generates a Fixnum hash value for this object. This 169 | * function must have the property that a.eql?(b) implies 170 | * a.hash == b.hash. The hash value is used by class 171 | * Hash. Any hash value that exceeds the capacity of a 172 | * Fixnum will be truncated before being used. 173 | */ 174 | 175 | int 176 | mrb_obj_id(mrb_value obj) 177 | { 178 | /* 179 | * 32-bit mrb_value space 180 | * MSB ------------------------ LSB 181 | * false 00000000000000000000000000000000 182 | * true 00000000000000000000000000000010 183 | * nil 00000000000000000000000000000100 184 | * undef 00000000000000000000000000000110 185 | * symbol ssssssssssssssssssssssss00001110 186 | * object oooooooooooooooooooooooooooooo00 = 0 (mod sizeof(RVALUE)) 187 | * fixnum fffffffffffffffffffffffffffffff1 188 | * 189 | * object_id space 190 | * LSB 191 | * false 00000000000000000000000000000000 192 | * true 00000000000000000000000000000010 193 | * nil 00000000000000000000000000000100 194 | * undef 00000000000000000000000000000110 195 | * symbol 000SSSSSSSSSSSSSSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4) 196 | * object oooooooooooooooooooooooooooooo0 o...o % A = 0 197 | * fixnum fffffffffffffffffffffffffffffff1 bignum if required 198 | * 199 | * where A = sizeof(RVALUE)/4 200 | * 201 | * sizeof(RVALUE) is 202 | * 20 if 32-bit, double is 4-byte aligned 203 | * 24 if 32-bit, double is 8-byte aligned 204 | * 40 if 64-bit 205 | */ 206 | /* 207 | * 128-bit mrb_value space 208 | * MSB -------- LSB 209 | * x86 [0,1] [2,3] [4,5] [6,7] [8,9] [A,B] [C,D] [E,F] 210 | * 7 6 5 4 3 2 1 0 211 | * 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 212 | * FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 213 | * false 0000000000000000 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000001 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx 214 | * true 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000010 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx 215 | * nil 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000001 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx 216 | * undef 0000000000000000 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000101 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx 217 | * symbol ssssssssssssssss ssssssssssssssss xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000100 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx 218 | * object oooooooooooooooo oooooooooooooo00 = 0 (mod sizeof(RVALUE)) 219 | (1)fixnum 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000011 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx 220 | * float 0000000000000001 0000000000000000 0000000000000000 0000000000000000 xxxxxxxx00000011 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx 221 | * <-- mrb_float --> xxxxxxxx00001101 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx 222 | * 223 | * object_id space 224 | * LSB 225 | * false 0000000000000000 0000000000000000 226 | * true 0000000000000000 0000000000000010 227 | * nil 0000000000000000 0000000000000100 228 | * undef 0000000000000000 0000000000000110 229 | * symbol 000SSSSSSSSSSSS SSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4) 230 | * object ooooooooooooooo ooooooooooooooo0 o...o % A = 0 231 | * fixnum ffffffffffffffff fffffffffffffff1 bignum if required 232 | * 233 | * where A = sizeof(RVALUE)/4 234 | * 235 | * sizeof(RVALUE) is 236 | * 20 if 32-bit, double is 4-byte aligned 237 | * 24 if 32-bit, double is 8-byte aligned 238 | * 40 if 64-bit 239 | */ 240 | /* tt:0_27 */ 241 | switch (mrb_type(obj)) { 242 | case MRB_TT_FREE: 243 | return 0; /* not define */ 244 | case MRB_TT_FALSE: 245 | if (mrb_nil_p(obj)) 246 | return 4; 247 | return 0; 248 | case MRB_TT_TRUE: 249 | return 2; 250 | case MRB_TT_FIXNUM: 251 | return mrb_fixnum(obj)*2+1; /* odd number */ 252 | case MRB_TT_SYMBOL: 253 | return SYM2ID(obj) * 2; 254 | case MRB_TT_UNDEF: 255 | return 0; /* not define */ 256 | case MRB_TT_FLOAT: 257 | return (int)mrb_float(obj)*2; /* even number */ 258 | case MRB_TT_OBJECT: 259 | case MRB_TT_CLASS: 260 | case MRB_TT_MODULE: 261 | case MRB_TT_ICLASS: 262 | case MRB_TT_SCLASS: 263 | case MRB_TT_PROC: 264 | case MRB_TT_ARRAY: 265 | case MRB_TT_HASH: 266 | case MRB_TT_STRING: 267 | case MRB_TT_RANGE: 268 | case MRB_TT_REGEX: 269 | case MRB_TT_STRUCT: 270 | case MRB_TT_EXCEPTION: 271 | case MRB_TT_MATCH: 272 | case MRB_TT_FILE: 273 | case MRB_TT_DATA: 274 | case MRB_TT_THREAD: 275 | case MRB_TT_THREADGRP: 276 | default: 277 | return mrb_fixnum(obj); /* even number */ 278 | } 279 | } 280 | 281 | -------------------------------------------------------------------------------- /src/eval_intern.h: -------------------------------------------------------------------------------- 1 | #ifndef RUBY_EVAL_INTERN_H 2 | #define RUBY_EVAL_INTERN_H 3 | 4 | //#include "ruby/ruby.h" 5 | #include "mruby.h" 6 | #define HAVE_STRING_H 7 | //#include "vm_core.h" 8 | #include "node.h" 9 | 10 | /* other frame flag */ 11 | #define VM_FRAME_FLAG_PASSED 0x0100 12 | #define PASS_PASSED_BLOCK_TH(th) do { \ 13 | (th)->passed_block = GC_GUARDED_PTR_REF((mrb_block_t *)(th)->cfp->lfp[0]); \ 14 | (th)->cfp->flag |= VM_FRAME_FLAG_PASSED; \ 15 | } while (0) 16 | 17 | #define PASS_PASSED_BLOCK() do { \ 18 | mrb_thread_t * const __th__ = GET_THREAD(); \ 19 | PASS_PASSED_BLOCK_TH(__th__); \ 20 | } while (0) 21 | 22 | #ifdef HAVE_STDLIB_H 23 | #include 24 | #endif 25 | #ifndef EXIT_SUCCESS 26 | #define EXIT_SUCCESS 0 27 | #endif 28 | #ifndef EXIT_FAILURE 29 | #define EXIT_FAILURE 1 30 | #endif 31 | 32 | #include 33 | #include 34 | 35 | #ifdef __APPLE__ 36 | #include 37 | #endif 38 | 39 | /* Make alloca work the best possible way. */ 40 | #ifdef __GNUC__ 41 | # ifndef atarist 42 | # ifndef alloca 43 | # define alloca __builtin_alloca 44 | # endif 45 | # endif /* atarist */ 46 | #else 47 | # ifdef HAVE_ALLOCA_H 48 | # include 49 | # else 50 | # ifdef _AIX 51 | #pragma alloca 52 | # else 53 | # ifndef alloca /* predefined by HP cc +Olibcalls */ 54 | void *alloca(); 55 | # endif 56 | # endif /* AIX */ 57 | # endif /* HAVE_ALLOCA_H */ 58 | #endif /* __GNUC__ */ 59 | 60 | #ifndef HAVE_STRING_H 61 | char *strrchr(const char *, const char); 62 | #endif 63 | 64 | #ifdef HAVE_UNISTD_H 65 | #include 66 | #endif 67 | 68 | #ifdef HAVE_NET_SOCKET_H 69 | #include 70 | #endif 71 | 72 | 73 | 74 | #include 75 | #include 76 | #include 77 | 78 | #ifdef HAVE_SYS_SELECT_H 79 | #include 80 | #endif 81 | 82 | /* 83 | Solaris sys/select.h switches select to select_large_fdset to support larger 84 | file descriptors if FD_SETSIZE is larger than 1024 on 32bit environment. 85 | But Ruby doesn't change FD_SETSIZE because fd_set is allocated dynamically. 86 | So following definition is required to use select_large_fdset. 87 | */ 88 | #ifdef HAVE_SELECT_LARGE_FDSET 89 | #define select(n, r, w, e, t) select_large_fdset(n, r, w, e, t) 90 | #endif 91 | 92 | #ifdef HAVE_SYS_PARAM_H 93 | #include 94 | #endif 95 | 96 | #include 97 | 98 | #define SAVE_ROOT_JMPBUF(th, stmt) do \ 99 | if (ruby_setjmp((th)->root_jmpbuf) == 0) { \ 100 | stmt; \ 101 | } while (0) 102 | 103 | #define TH_PUSH_TAG(th) do { \ 104 | mrb_thread_t * const _th = th; \ 105 | struct mrb_vm_tag _tag; \ 106 | _tag.tag = 0; \ 107 | _tag.prev = _th->tag; \ 108 | _th->tag = &_tag; 109 | 110 | #define TH_POP_TAG() \ 111 | _th->tag = _tag.prev; \ 112 | } while (0) 113 | 114 | #define TH_POP_TAG2() \ 115 | _th->tag = _tag.prev 116 | 117 | #define PUSH_TAG() TH_PUSH_TAG(GET_THREAD()) 118 | #define POP_TAG() TH_POP_TAG() 119 | 120 | #define TH_EXEC_TAG() ruby_setjmp(_th->tag->buf) 121 | 122 | #define EXEC_TAG() \ 123 | TH_EXEC_TAG() 124 | 125 | #define TH_JUMP_TAG(th, st) do { \ 126 | ruby_longjmp(th->tag->buf,(st)); \ 127 | } while (0) 128 | 129 | //#define JUMP_TAG(st) TH_JUMP_TAG(GET_THREAD(), st) 130 | 131 | enum ruby_tag_type { 132 | RUBY_TAG_RETURN = 0x1, 133 | RUBY_TAG_BREAK = 0x2, 134 | RUBY_TAG_NEXT = 0x3, 135 | RUBY_TAG_RETRY = 0x4, 136 | RUBY_TAG_REDO = 0x5, 137 | RUBY_TAG_RAISE = 0x6, 138 | RUBY_TAG_THROW = 0x7, 139 | RUBY_TAG_FATAL = 0x8, 140 | RUBY_TAG_MASK = 0xf 141 | }; 142 | #define TAG_RETURN RUBY_TAG_RETURN 143 | #define TAG_BREAK RUBY_TAG_BREAK 144 | #define TAG_NEXT RUBY_TAG_NEXT 145 | #define TAG_RETRY RUBY_TAG_RETRY 146 | #define TAG_REDO RUBY_TAG_REDO 147 | #define TAG_RAISE RUBY_TAG_RAISE 148 | #define TAG_THROW RUBY_TAG_THROW 149 | #define TAG_FATAL RUBY_TAG_FATAL 150 | #define TAG_MASK RUBY_TAG_MASK 151 | 152 | #define NEW_THROW_OBJECT(val, pt, st) \ 153 | ((mrb_value)mrb_node_newnode(NODE_LIT, (mrb_value)(val), (mrb_value)(pt), (mrb_value)(st))) 154 | //#define SET_THROWOBJ_CATCH_POINT(obj, val) 155 | // (RNODE((obj))->u2.value = (val)) 156 | //#define SET_THROWOBJ_STATE(obj, val) 157 | // (RNODE((obj))->u3.value = (val)) 158 | 159 | #define GET_THROWOBJ_VAL(obj) ((mrb_value)RNODE((obj))->u1.value) 160 | #define GET_THROWOBJ_CATCH_POINT(obj) ((mrb_value*)RNODE((obj))->u2.value) 161 | #define GET_THROWOBJ_STATE(obj) ((int)RNODE((obj))->u3.value) 162 | 163 | #define SCOPE_TEST(f) (mrb_vm_cref()->nd_visi & (f)) 164 | #define SCOPE_CHECK(f) (mrb_vm_cref()->nd_visi == (f)) 165 | #define SCOPE_SET(f) (mrb_vm_cref()->nd_visi = (f)) 166 | 167 | #define sysstack_error mrb_fixnum_value(0) 168 | 169 | #define CHECK_STACK_OVERFLOW(mrb, cfp, margin) do \ 170 | if ((mrb_value *)((char *)(((mrb_value *)(cfp)->sp) + (margin)) + sizeof(mrb_control_frame_t)) >= ((mrb_value *)cfp)) { \ 171 | mrb_exc_raise(mrb, sysstack_error); \ 172 | } \ 173 | while (0) 174 | 175 | void mrb_thread_cleanup(void); 176 | void mrb_thread_wait_other_threads(void); 177 | 178 | enum { 179 | RAISED_EXCEPTION = 1, 180 | RAISED_STACKOVERFLOW = 2, 181 | RAISED_NOMEMORY = 4 182 | }; 183 | //int rb_threadptr_set_raised(mrb_thread_t *th); 184 | //int rb_threadptr_reset_raised(mrb_thread_t *th); 185 | #define mrb_thread_raised_set(th, f) ((th)->raised_flag |= (f)) 186 | #define mrb_thread_raised_reset(th, f) ((th)->raised_flag &= ~(f)) 187 | #define mrb_thread_raised_p(th, f) (((th)->raised_flag & (f)) != 0) 188 | #define mrb_thread_raised_clear(th) ((th)->raised_flag = 0) 189 | 190 | //mrb_value mrb_f_eval(int argc, mrb_value *argv, mrb_value self); 191 | //mrb_value mrb_make_exception(int argc, mrb_value *argv); 192 | #ifndef NORETURN 193 | # define NORETURN(x) x 194 | #endif 195 | #ifndef DEPRECATED 196 | # define DEPRECATED(x) x 197 | #endif 198 | 199 | NORETURN(void mrb_fiber_start(void)); 200 | 201 | NORETURN(void rb_print_undef(mrb_value, mrb_sym, int)); 202 | NORETURN(void rb_vm_localjump_error(const char *,mrb_value, int)); 203 | NORETURN(void rb_vm_jump_tag_but_local_jump(int, mrb_value)); 204 | //NORETURN(void mrb_raise_method_missing(mrb_thread_t *th, int argc, mrb_value *argv, 205 | // mrb_value obj, int call_status)); 206 | 207 | mrb_value mrb_vm_make_jump_tag_but_local_jump(int state, mrb_value val); 208 | NODE *mrb_vm_cref(void); 209 | //mrb_value rb_vm_call_cfunc(mrb_value recv, mrb_value (*func)(mrb_value), mrb_value arg, const mrb_block_t *blockptr, mrb_value filename, mrb_value filepath); 210 | void mrb_vm_set_progname(mrb_value filename); 211 | void mrb_thread_terminate_all(mrb_state *mrb); 212 | //mrb_value mrb_vm_top_self(); 213 | mrb_value mrb_vm_cbase(void); 214 | //int mrb_vm_get_sourceline(const mrb_control_frame_t *); 215 | void mrb_trap_restore_mask(void); 216 | 217 | #endif /* RUBY_EVAL_INTERN_H */ 218 | -------------------------------------------------------------------------------- /src/ext/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matz/mruby/8a5943f2540cf43bb15789bc519e1b355d479fed/src/ext/.gitkeep -------------------------------------------------------------------------------- /src/gc.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_GC_H 2 | #define MRUBY_GC_H 3 | 4 | typedef struct { 5 | union { 6 | struct free_obj { 7 | MRUBY_OBJECT_HEADER; 8 | struct RBasic *next; 9 | } free; 10 | struct RBasic basic; 11 | struct RObject object; 12 | struct RClass klass; 13 | struct RString string; 14 | struct RArray array; 15 | struct RHash hash; 16 | struct RRange range; 17 | struct RStruct structdata; 18 | struct RProc procdata; 19 | #ifdef INCLUDE_REGEXP 20 | struct RMatch match; 21 | struct RRegexp regexp; 22 | #endif 23 | } as; 24 | } RVALUE; 25 | 26 | #endif /* MRUBY_GC_H */ 27 | -------------------------------------------------------------------------------- /src/init.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | 3 | void mrb_init_class(mrb_state*); 4 | void mrb_init_symtbl(mrb_state*); 5 | void mrb_init_symbols(mrb_state*); 6 | void mrb_init_object(mrb_state*); 7 | void mrb_init_kernel(mrb_state*); 8 | void mrb_init_enumerable(mrb_state*); 9 | void mrb_init_comparable(mrb_state*); 10 | void mrb_init_array(mrb_state*); 11 | void mrb_init_hash(mrb_state*); 12 | void mrb_init_numeric(mrb_state*); 13 | void mrb_init_proc(mrb_state*); 14 | void mrb_init_range(mrb_state*); 15 | void mrb_init_string(mrb_state*); 16 | void mrb_init_regexp(mrb_state*); 17 | void mrb_init_encoding(mrb_state*); 18 | void mrb_init_exception(mrb_state*); 19 | void mrb_init_time(mrb_state *); 20 | void mrb_init_io(mrb_state *); 21 | void mrb_init_file(mrb_state *); 22 | void mrb_init_thread(mrb_state *); 23 | void mrb_init_struct(mrb_state *); 24 | void mrb_init_gc(mrb_state *); 25 | void Init_var_tables(mrb_state *mrb); 26 | void Init_version(mrb_state *mrb); 27 | void mrb_init_print(mrb_state *mrb); 28 | void mrb_init_mrblib(mrb_state *mrb); 29 | 30 | #define MANDEL 31 | #ifdef MANDEL 32 | #include 33 | #include 34 | static mrb_value 35 | mpow(mrb_state *mrb, mrb_value obj) 36 | { 37 | mrb_float x, y; 38 | 39 | mrb_get_args(mrb, "ff", &x, &y); 40 | x = pow(x, y); 41 | 42 | return mrb_float_value(x); 43 | } 44 | 45 | static mrb_value 46 | msqrt(mrb_state *mrb, mrb_value obj) 47 | { 48 | mrb_float x; 49 | 50 | mrb_get_args(mrb, "f", &x); 51 | x = sqrt(x); 52 | 53 | return mrb_float_value(x); 54 | } 55 | 56 | static mrb_value 57 | mputc(mrb_state *mrb, mrb_value obj) 58 | { 59 | int x; 60 | 61 | mrb_get_args(mrb, "i", &x); 62 | putc(x, stdout); 63 | 64 | return mrb_nil_value(); 65 | } 66 | #endif 67 | 68 | void 69 | mrb_init_core(mrb_state *mrb) 70 | { 71 | mrb_init_symtbl(mrb); 72 | 73 | mrb_init_class(mrb); 74 | mrb_init_object(mrb); 75 | mrb_init_kernel(mrb); 76 | mrb_init_comparable(mrb); 77 | mrb_init_enumerable(mrb); 78 | 79 | mrb_init_symbols(mrb); 80 | mrb_init_proc(mrb); 81 | mrb_init_string(mrb); 82 | Init_version(mrb); /* after init_string */ 83 | mrb_init_array(mrb); 84 | mrb_init_hash(mrb); 85 | mrb_init_numeric(mrb); 86 | mrb_init_range(mrb); 87 | mrb_init_struct(mrb); 88 | mrb_init_gc(mrb); 89 | #ifdef INCLUDE_REGEXP 90 | mrb_init_regexp(mrb); 91 | mrb_init_encoding(mrb); 92 | #endif 93 | mrb_init_exception(mrb); 94 | mrb_init_print(mrb); 95 | 96 | #ifdef MANDEL 97 | mrb_define_method(mrb, mrb->kernel_module, "pow", mpow, ARGS_REQ(2)); 98 | mrb_define_method(mrb, mrb->kernel_module, "sqrt", msqrt, ARGS_REQ(1)); 99 | mrb_define_method(mrb, mrb->kernel_module, "putc", mputc, ARGS_REQ(1)); 100 | #endif 101 | 102 | mrb_init_mrblib(mrb); 103 | 104 | mrb_gc_arena_restore(mrb, 0); 105 | } 106 | -------------------------------------------------------------------------------- /src/init_ext.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | 3 | void 4 | mrb_init_ext(mrb_state *mrb) 5 | { 6 | #ifdef INCLUDE_SOCKET 7 | extern void mrb_init_socket(mrb_state *mrb); 8 | mrb_init_socket(mrb); 9 | #endif 10 | } 11 | -------------------------------------------------------------------------------- /src/irep.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_IREP_H 2 | #define MRUBY_IREP_H 3 | 4 | typedef struct mrb_irep { 5 | int idx; 6 | 7 | int flags; 8 | int nlocals; 9 | int nregs; 10 | 11 | mrb_code *iseq; 12 | mrb_value *pool; 13 | int *syms; 14 | 15 | int ilen, plen, slen; 16 | } mrb_irep; 17 | 18 | #define MRB_IREP_NOFREE 3 19 | #define MRB_ISEQ_NOFREE 1 20 | 21 | void mrb_add_irep(mrb_state *mrb, int n); 22 | 23 | #endif /* MRUBY_IREP_H */ 24 | -------------------------------------------------------------------------------- /src/keywords: -------------------------------------------------------------------------------- 1 | %{ 2 | struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;}; 3 | const struct kwtable *mrb_reserved_word(const char *, unsigned int); 4 | static const struct kwtable *reserved_word(const char *, unsigned int); 5 | #define mrb_reserved_word(str, len) reserved_word(str, len) 6 | %} 7 | 8 | struct kwtable; 9 | %% 10 | __ENCODING__, {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END 11 | __LINE__, {keyword__LINE__, keyword__LINE__}, EXPR_END 12 | __FILE__, {keyword__FILE__, keyword__FILE__}, EXPR_END 13 | BEGIN, {keyword_BEGIN, keyword_BEGIN}, EXPR_END 14 | END, {keyword_END, keyword_END}, EXPR_END 15 | alias, {keyword_alias, keyword_alias}, EXPR_FNAME 16 | and, {keyword_and, keyword_and}, EXPR_VALUE 17 | begin, {keyword_begin, keyword_begin}, EXPR_BEG 18 | break, {keyword_break, keyword_break}, EXPR_MID 19 | case, {keyword_case, keyword_case}, EXPR_VALUE 20 | class, {keyword_class, keyword_class}, EXPR_CLASS 21 | def, {keyword_def, keyword_def}, EXPR_FNAME 22 | do, {keyword_do, keyword_do}, EXPR_BEG 23 | else, {keyword_else, keyword_else}, EXPR_BEG 24 | elsif, {keyword_elsif, keyword_elsif}, EXPR_VALUE 25 | end, {keyword_end, keyword_end}, EXPR_END 26 | ensure, {keyword_ensure, keyword_ensure}, EXPR_BEG 27 | false, {keyword_false, keyword_false}, EXPR_END 28 | for, {keyword_for, keyword_for}, EXPR_VALUE 29 | if, {keyword_if, modifier_if}, EXPR_VALUE 30 | in, {keyword_in, keyword_in}, EXPR_VALUE 31 | module, {keyword_module, keyword_module}, EXPR_VALUE 32 | next, {keyword_next, keyword_next}, EXPR_MID 33 | nil, {keyword_nil, keyword_nil}, EXPR_END 34 | not, {keyword_not, keyword_not}, EXPR_ARG 35 | or, {keyword_or, keyword_or}, EXPR_VALUE 36 | redo, {keyword_redo, keyword_redo}, EXPR_END 37 | rescue, {keyword_rescue, modifier_rescue}, EXPR_MID 38 | retry, {keyword_retry, keyword_retry}, EXPR_END 39 | return, {keyword_return, keyword_return}, EXPR_MID 40 | self, {keyword_self, keyword_self}, EXPR_END 41 | super, {keyword_super, keyword_super}, EXPR_ARG 42 | then, {keyword_then, keyword_then}, EXPR_BEG 43 | true, {keyword_true, keyword_true}, EXPR_END 44 | undef, {keyword_undef, keyword_undef}, EXPR_FNAME 45 | unless, {keyword_unless, modifier_unless}, EXPR_VALUE 46 | until, {keyword_until, modifier_until}, EXPR_VALUE 47 | when, {keyword_when, keyword_when}, EXPR_VALUE 48 | while, {keyword_while, modifier_while}, EXPR_VALUE 49 | yield, {keyword_yield, keyword_yield}, EXPR_ARG 50 | %% 51 | -------------------------------------------------------------------------------- /src/lex.def: -------------------------------------------------------------------------------- 1 | /* C code produced by gperf version 3.0.3 */ 2 | /* Command-line: gperf -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' keywords */ 3 | 4 | #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ 5 | && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ 6 | && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ 7 | && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ 8 | && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ 9 | && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ 10 | && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ 11 | && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ 12 | && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ 13 | && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ 14 | && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ 15 | && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ 16 | && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ 17 | && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ 18 | && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ 19 | && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ 20 | && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ 21 | && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ 22 | && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ 23 | && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ 24 | && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ 25 | && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ 26 | && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) 27 | /* The character set is not based on ISO-646. */ 28 | error "gperf generated tables don't work with this execution character set. Please report a bug to ." 29 | #endif 30 | 31 | #line 1 "keywords" 32 | 33 | struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;}; 34 | const struct kwtable *mrb_reserved_word(const char *, unsigned int); 35 | static const struct kwtable *reserved_word(const char *, unsigned int); 36 | #define mrb_reserved_word(str, len) reserved_word(str, len) 37 | #line 8 "keywords" 38 | struct kwtable; 39 | 40 | #define TOTAL_KEYWORDS 40 41 | #define MIN_WORD_LENGTH 2 42 | #define MAX_WORD_LENGTH 12 43 | #define MIN_HASH_VALUE 8 44 | #define MAX_HASH_VALUE 50 45 | /* maximum key range = 43, duplicates = 0 */ 46 | 47 | #ifdef __GNUC__ 48 | __inline 49 | #else 50 | #ifdef __cplusplus 51 | inline 52 | #endif 53 | #endif 54 | static unsigned int 55 | hash (str, len) 56 | register const char *str; 57 | register unsigned int len; 58 | { 59 | static const unsigned char asso_values[] = 60 | { 61 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 62 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 63 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 64 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 65 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 66 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 67 | 51, 51, 51, 51, 51, 51, 14, 51, 16, 8, 68 | 11, 13, 51, 51, 51, 51, 10, 51, 13, 51, 69 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 70 | 51, 51, 51, 51, 51, 11, 51, 13, 1, 26, 71 | 4, 1, 8, 28, 51, 23, 51, 1, 1, 27, 72 | 5, 19, 21, 51, 8, 3, 3, 11, 51, 21, 73 | 24, 16, 51, 51, 51, 51, 51, 51, 51, 51, 74 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 75 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 76 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 77 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 78 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 79 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 80 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 81 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 82 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 83 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 84 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 85 | 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 86 | 51, 51, 51, 51, 51, 51 87 | }; 88 | register int hval = len; 89 | 90 | switch (hval) 91 | { 92 | default: 93 | hval += asso_values[(unsigned char)str[2]]; 94 | /*FALLTHROUGH*/ 95 | case 2: 96 | case 1: 97 | hval += asso_values[(unsigned char)str[0]]; 98 | break; 99 | } 100 | return hval + asso_values[(unsigned char)str[len - 1]]; 101 | } 102 | 103 | #ifdef __GNUC__ 104 | __inline 105 | #ifdef __GNUC_STDC_INLINE__ 106 | __attribute__ ((__gnu_inline__)) 107 | #endif 108 | #endif 109 | const struct kwtable * 110 | mrb_reserved_word (str, len) 111 | register const char *str; 112 | register unsigned int len; 113 | { 114 | static const struct kwtable wordlist[] = 115 | { 116 | {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, 117 | #line 18 "keywords" 118 | {"break", {keyword_break, keyword_break}, EXPR_MID}, 119 | #line 23 "keywords" 120 | {"else", {keyword_else, keyword_else}, EXPR_BEG}, 121 | #line 33 "keywords" 122 | {"nil", {keyword_nil, keyword_nil}, EXPR_END}, 123 | #line 26 "keywords" 124 | {"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG}, 125 | #line 25 "keywords" 126 | {"end", {keyword_end, keyword_end}, EXPR_END}, 127 | #line 42 "keywords" 128 | {"then", {keyword_then, keyword_then}, EXPR_BEG}, 129 | #line 34 "keywords" 130 | {"not", {keyword_not, keyword_not}, EXPR_ARG}, 131 | #line 27 "keywords" 132 | {"false", {keyword_false, keyword_false}, EXPR_END}, 133 | #line 40 "keywords" 134 | {"self", {keyword_self, keyword_self}, EXPR_END}, 135 | #line 24 "keywords" 136 | {"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE}, 137 | #line 37 "keywords" 138 | {"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID}, 139 | #line 43 "keywords" 140 | {"true", {keyword_true, keyword_true}, EXPR_END}, 141 | #line 46 "keywords" 142 | {"until", {keyword_until, modifier_until}, EXPR_VALUE}, 143 | #line 45 "keywords" 144 | {"unless", {keyword_unless, modifier_unless}, EXPR_VALUE}, 145 | #line 39 "keywords" 146 | {"return", {keyword_return, keyword_return}, EXPR_MID}, 147 | #line 21 "keywords" 148 | {"def", {keyword_def, keyword_def}, EXPR_FNAME}, 149 | #line 16 "keywords" 150 | {"and", {keyword_and, keyword_and}, EXPR_VALUE}, 151 | #line 22 "keywords" 152 | {"do", {keyword_do, keyword_do}, EXPR_BEG}, 153 | #line 49 "keywords" 154 | {"yield", {keyword_yield, keyword_yield}, EXPR_ARG}, 155 | #line 28 "keywords" 156 | {"for", {keyword_for, keyword_for}, EXPR_VALUE}, 157 | #line 44 "keywords" 158 | {"undef", {keyword_undef, keyword_undef}, EXPR_FNAME}, 159 | #line 35 "keywords" 160 | {"or", {keyword_or, keyword_or}, EXPR_VALUE}, 161 | #line 30 "keywords" 162 | {"in", {keyword_in, keyword_in}, EXPR_VALUE}, 163 | #line 47 "keywords" 164 | {"when", {keyword_when, keyword_when}, EXPR_VALUE}, 165 | #line 38 "keywords" 166 | {"retry", {keyword_retry, keyword_retry}, EXPR_END}, 167 | #line 29 "keywords" 168 | {"if", {keyword_if, modifier_if}, EXPR_VALUE}, 169 | #line 19 "keywords" 170 | {"case", {keyword_case, keyword_case}, EXPR_VALUE}, 171 | #line 36 "keywords" 172 | {"redo", {keyword_redo, keyword_redo}, EXPR_END}, 173 | #line 32 "keywords" 174 | {"next", {keyword_next, keyword_next}, EXPR_MID}, 175 | #line 41 "keywords" 176 | {"super", {keyword_super, keyword_super}, EXPR_ARG}, 177 | #line 31 "keywords" 178 | {"module", {keyword_module, keyword_module}, EXPR_VALUE}, 179 | #line 17 "keywords" 180 | {"begin", {keyword_begin, keyword_begin}, EXPR_BEG}, 181 | #line 11 "keywords" 182 | {"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END}, 183 | #line 12 "keywords" 184 | {"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END}, 185 | #line 10 "keywords" 186 | {"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END}, 187 | #line 14 "keywords" 188 | {"END", {keyword_END, keyword_END}, EXPR_END}, 189 | #line 15 "keywords" 190 | {"alias", {keyword_alias, keyword_alias}, EXPR_FNAME}, 191 | #line 13 "keywords" 192 | {"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END}, 193 | {""}, 194 | #line 20 "keywords" 195 | {"class", {keyword_class, keyword_class}, EXPR_CLASS}, 196 | {""}, {""}, 197 | #line 48 "keywords" 198 | {"while", {keyword_while, modifier_while}, EXPR_VALUE} 199 | }; 200 | 201 | if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 202 | { 203 | register int key = hash (str, len); 204 | 205 | if (key <= MAX_HASH_VALUE && key >= 0) 206 | { 207 | register const char *s = wordlist[key].name; 208 | 209 | if (*str == *s && !strcmp (str + 1, s + 1)) 210 | return &wordlist[key]; 211 | } 212 | } 213 | return 0; 214 | } 215 | #line 50 "keywords" 216 | 217 | -------------------------------------------------------------------------------- /src/mdata.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | mdata.h - 4 | 5 | 6 | Copyright (C) 2007 Yukihiro Matsumoto 7 | 8 | **********************************************************************/ 9 | 10 | #ifndef RUBY_DATA_H 11 | #define RUBY_DATA_H 1 12 | 13 | #if defined(__cplusplus) 14 | extern "C" { 15 | #endif 16 | 17 | 18 | struct mrb_data_type { 19 | const char *struct_name; 20 | void (*dfree)(mrb_state *mrb, void*); 21 | }; 22 | 23 | struct RData { 24 | MRUBY_OBJECT_HEADER; 25 | struct kh_iv *iv; 26 | struct mrb_data_type *type; 27 | void *data; 28 | }; 29 | 30 | struct RData *mrb_data_object_alloc(mrb_state *mrb, struct RClass* klass, void *datap, const struct mrb_data_type *type); 31 | 32 | #define Data_Wrap_Struct(mrb,klass,type,ptr)\ 33 | mrb_data_object_alloc(mrb,klass,ptr,type) 34 | 35 | #define Data_Make_Struct(mrb,klass,strct,type,sval) (\ 36 | sval = mrb_malloc(mrb, sizeof(strct)),\ 37 | memset(sval, 0, sizeof(strct)),\ 38 | Data_Wrap_Struct(mrb,klass,type,sval)\ 39 | ) 40 | 41 | #define RDATA(obj) ((struct RData *)((obj).value.p)) 42 | #define DATA_PTR(d) (RDATA(d)->data) 43 | #define DATA_TYPE(d) (RDATA(d)->type) 44 | void *mrb_check_datatype(mrb_state *mrb, mrb_value, const struct mrb_data_type*); 45 | #define Data_Get_Struct(mrb,obj,type,sval) do {\ 46 | sval = mrb_check_datatype(mrb, obj, type); \ 47 | } while (0) 48 | 49 | #if defined(__cplusplus) 50 | } /* extern "C" { */ 51 | #endif 52 | 53 | #endif /* RUBY_DATA_H */ 54 | -------------------------------------------------------------------------------- /src/method.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | method.h - 4 | 5 | $Author: ko1 $ 6 | created at: Wed Jul 15 20:02:33 2009 7 | 8 | Copyright (C) 2009 Koichi Sasada 9 | 10 | **********************************************************************/ 11 | #ifndef METHOD_H 12 | #define METHOD_H 13 | 14 | typedef enum { 15 | NOEX_PUBLIC = 0x00, 16 | NOEX_NOSUPER = 0x01, 17 | NOEX_PRIVATE = 0x02, 18 | NOEX_PROTECTED = 0x04, 19 | NOEX_MASK = 0x06, 20 | NOEX_BASIC = 0x08, 21 | NOEX_UNDEF = NOEX_NOSUPER, 22 | NOEX_MODFUNC = 0x12, 23 | NOEX_SUPER = 0x20, 24 | NOEX_VCALL = 0x40, 25 | NOEX_RESPONDS = 0x80 26 | } mrb_method_flag_t; 27 | 28 | #define NOEX_SAFE(n) ((int)((n) >> 8) & 0x0F) 29 | #define NOEX_WITH(n, s) ((s << 8) | (n) | (ruby_running ? 0 : NOEX_BASIC)) 30 | #define NOEX_WITH_SAFE(n) NOEX_WITH(n, mrb_safe_level()) 31 | 32 | /* method data type */ 33 | 34 | typedef enum { 35 | VM_METHOD_TYPE_ISEQ, 36 | VM_METHOD_TYPE_CFUNC, 37 | VM_METHOD_TYPE_ATTRSET, 38 | VM_METHOD_TYPE_IVAR, 39 | VM_METHOD_TYPE_BMETHOD, 40 | VM_METHOD_TYPE_ZSUPER, 41 | VM_METHOD_TYPE_UNDEF, 42 | VM_METHOD_TYPE_NOTIMPLEMENTED, 43 | VM_METHOD_TYPE_OPTIMIZED, /* Kernel#send, Proc#call, etc */ 44 | VM_METHOD_TYPE_MISSING /* wrapper for method_missing(id) */ 45 | } mrb_method_type_t; 46 | 47 | typedef struct mrb_method_cfunc_struct { 48 | mrb_value (*func)(ANYARGS); 49 | int argc; 50 | } mrb_method_cfunc_t; 51 | 52 | typedef struct mrb_method_attr_struct { 53 | mrb_sym id; 54 | mrb_value location; 55 | } mrb_method_attr_t; 56 | 57 | typedef struct mrb_iseq_struct mrb_iseq_t; 58 | 59 | typedef struct mrb_method_definition_struct { 60 | mrb_method_type_t type; /* method type */ 61 | mrb_sym original_id; 62 | union { 63 | mrb_iseq_t *iseq; /* should be mark */ 64 | mrb_method_cfunc_t cfunc; 65 | mrb_method_attr_t attr; 66 | mrb_value proc; /* should be mark */ 67 | enum method_optimized_type { 68 | OPTIMIZED_METHOD_TYPE_SEND, 69 | OPTIMIZED_METHOD_TYPE_CALL 70 | } optimize_type; 71 | } body; 72 | int alias_count; 73 | } mrb_method_definition_t; 74 | 75 | typedef struct mrb_method_entry_struct { 76 | mrb_method_flag_t flag; 77 | char mark; 78 | mrb_method_definition_t *def; 79 | mrb_sym called_id; 80 | mrb_value klass; /* should be mark */ 81 | } mrb_method_entry_t; 82 | 83 | struct unlinked_method_entry_list_entry { 84 | struct unlinked_method_entry_list_entry *next; 85 | mrb_method_entry_t *me; 86 | }; 87 | 88 | #define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF) 89 | 90 | void mrb_add_method_cfunc(mrb_value klass, mrb_sym mid, mrb_value (*func)(ANYARGS), int argc, mrb_method_flag_t noex); 91 | mrb_method_entry_t *mrb_add_method(mrb_value klass, mrb_sym mid, mrb_method_type_t type, void *option, mrb_method_flag_t noex); 92 | mrb_method_entry_t *mrb_method_entry(mrb_state *mrb, mrb_value klass, mrb_sym id); 93 | 94 | mrb_method_entry_t *mrb_method_entry_get_without_cache(mrb_value klass, mrb_sym id); 95 | mrb_method_entry_t *mrb_method_entry_set(mrb_value klass, mrb_sym mid, const mrb_method_entry_t *, mrb_method_flag_t noex); 96 | 97 | int mrb_method_entry_arity(const mrb_method_entry_t *me); 98 | 99 | void mrb_mark_method_entry(const mrb_method_entry_t *me); 100 | void mrb_free_method_entry(mrb_method_entry_t *me); 101 | void mrb_sweep_method_entry(void *vm); 102 | 103 | #endif /* METHOD_H */ 104 | -------------------------------------------------------------------------------- /src/minimain.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include "mruby/proc.h" 3 | 4 | #if 0 5 | #include "opcode.h" 6 | 7 | mrb_code fib_iseq[256]; 8 | 9 | int fib_syms[4]; 10 | 11 | mrb_irep fib_irep = { 12 | 1, 13 | MRB_IREP_NOFREE, 14 | 2, 15 | 5, 16 | fib_iseq, 17 | NULL, 18 | fib_syms, 19 | 20 | 256, 0, 4, 21 | }; 22 | 23 | mrb_code main_iseq[256]; 24 | 25 | int main_syms[2]; 26 | 27 | mrb_irep main_irep = { 28 | 0, 29 | MRB_IREP_NOFREE, 30 | 1, 31 | 3, 32 | main_iseq, 33 | NULL, 34 | main_syms, 35 | 36 | 256, 0, 2, 37 | }; 38 | 39 | int 40 | main(int argc, char **argv) 41 | { 42 | mrb_state *mrb = mrb_open(); 43 | int sirep = mrb->irep_len; 44 | int n; 45 | 46 | main_syms[0] = mrb_intern(mrb, "fib"); 47 | main_syms[1] = mrb_intern(mrb, "p"); 48 | n = 0; 49 | 50 | main_iseq[n++] = MKOP_AB(OP_LAMBDA, 1, 1); /* r1 := lambda(1) */ 51 | main_iseq[n++] = MKOP_AB(OP_METHOD, 1, 0); /* defmethod(r1) */ 52 | main_iseq[n++] = MKOP_AB(OP_MOVE, 1, 0); /* r1 := r0 */ 53 | main_iseq[n++] = MKOP_AB(OP_MOVE, 2, 0); /* r2 := r0 */ 54 | main_iseq[n++] = MKOP_AsBx(OP_LOADI, 3, 35); /* r3 := 20 */ 55 | main_iseq[n++] = MKOP_ABC(OP_SEND, 2, 0, 1); /* r2 .fib r3 */ 56 | main_iseq[n++] = MKOP_ABC(OP_SEND, 1, 1, 1); /* r1 .p r2 */ 57 | main_iseq[n++] = MKOP_ABC(OP_STOP, 1, 1, 2); /* stop */ 58 | main_irep.ilen = n; 59 | main_irep.idx = sirep; 60 | 61 | fib_syms[0] = mrb_intern(mrb, "<"); 62 | fib_syms[1] = mrb_intern(mrb, "-"); 63 | fib_syms[2] = mrb_intern(mrb, "+"); 64 | fib_syms[3] = mrb_intern(mrb, "fib"); 65 | n = 0; 66 | 67 | fib_iseq[n++] = MKOP_AB(OP_MOVE, 2, 1); /* r2 := r1 */ 68 | fib_iseq[n++] = MKOP_AsBx(OP_LOADI, 3, 3); /* r3 := 2 */ 69 | fib_iseq[n++] = MKOP_ABC(OP_LT, 2, 0, 2); /* r2 .< r3 */ 70 | fib_iseq[n++] = MKOP_AsBx(OP_JMPNOT, 2, 2); /* ifnot r2 :else */ 71 | fib_iseq[n++] = MKOP_AsBx(OP_LOADI, 2, 1); /* r6 := 1 */ 72 | fib_iseq[n++] = MKOP_A(OP_RETURN, 2); /* return r2 */ 73 | fib_iseq[n++] = MKOP_AB(OP_MOVE, 3, 0); /* r3 := r0 :else */ 74 | fib_iseq[n++] = MKOP_AB(OP_MOVE, 4, 1); /* r4 := r1 */ 75 | fib_iseq[n++] = MKOP_ABC(OP_SUBI, 4, 1, 2); /* r4 .- 2 */ 76 | fib_iseq[n++] = MKOP_ABC(OP_SEND, 3, 3, 1); /* r3 .fib r4 */ 77 | fib_iseq[n++] = MKOP_AB(OP_MOVE, 4, 0); /* r4 := r0 */ 78 | fib_iseq[n++] = MKOP_AB(OP_MOVE, 5, 1); /* r5 := r1 */ 79 | fib_iseq[n++] = MKOP_ABC(OP_SUBI, 5, 1, 1); /* r5 .- 1 */ 80 | fib_iseq[n++] = MKOP_ABC(OP_SEND, 4, 3, 1); /* r4 .fib :r5 */ 81 | fib_iseq[n++] = MKOP_ABC(OP_ADD, 3, 2, 1); /* r3 .+ r4 */ 82 | fib_iseq[n++] = MKOP_A(OP_RETURN, 3); /* return r3 */ 83 | fib_irep.ilen = n; 84 | fib_irep.idx = sirep+1; 85 | 86 | mrb_add_irep(mrb, sirep+2); 87 | mrb->irep[sirep ] = &main_irep; 88 | mrb->irep[sirep+1] = &fib_irep; 89 | 90 | mrb_run(mrb, mrb_proc_new(mrb, &main_irep), mrb_nil_value()); 91 | } 92 | 93 | #else 94 | #include "compile.h" 95 | 96 | int 97 | main() 98 | { 99 | mrb_state *mrb = mrb_open(); 100 | int n; 101 | 102 | n = mrb_compile_string(mrb, "\ 103 | def fib(n)\n\ 104 | if n<2\n\ 105 | n\n\ 106 | else\n\ 107 | fib(n-2)+fib(n-1)\n\ 108 | end\n\ 109 | end\n\ 110 | p(fib(30), \"\\n\")\n\ 111 | "); 112 | mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_nil_value()); 113 | 114 | return 0; 115 | } 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /src/node.h: -------------------------------------------------------------------------------- 1 | enum node_type { 2 | NODE_METHOD, 3 | NODE_FBODY, 4 | NODE_CFUNC, 5 | NODE_SCOPE, 6 | NODE_BLOCK, 7 | NODE_IF, 8 | NODE_CASE, 9 | NODE_WHEN, 10 | NODE_OPT_N, 11 | NODE_WHILE, 12 | NODE_UNTIL, 13 | NODE_ITER, 14 | NODE_FOR, 15 | NODE_BREAK, 16 | NODE_NEXT, 17 | NODE_REDO, 18 | NODE_RETRY, 19 | NODE_BEGIN, 20 | NODE_RESCUE, 21 | NODE_ENSURE, 22 | NODE_AND, 23 | NODE_OR, 24 | NODE_NOT, 25 | NODE_MASGN, 26 | NODE_ASGN, 27 | NODE_CDECL, 28 | NODE_CVASGN, 29 | NODE_CVDECL, 30 | NODE_OP_ASGN, 31 | NODE_CALL, 32 | NODE_FCALL, 33 | NODE_VCALL, 34 | NODE_SUPER, 35 | NODE_ZSUPER, 36 | NODE_ARRAY, 37 | NODE_ZARRAY, 38 | NODE_HASH, 39 | NODE_RETURN, 40 | NODE_YIELD, 41 | NODE_LVAR, 42 | NODE_DVAR, 43 | NODE_GVAR, 44 | NODE_IVAR, 45 | NODE_CONST, 46 | NODE_CVAR, 47 | NODE_NTH_REF, 48 | NODE_BACK_REF, 49 | NODE_MATCH, 50 | NODE_MATCH2, 51 | NODE_MATCH3, 52 | NODE_INT, 53 | NODE_FLOAT, 54 | NODE_NEGATE, 55 | NODE_LAMBDA, 56 | NODE_SYM, 57 | NODE_STR, 58 | NODE_DSTR, 59 | NODE_DREGX, 60 | NODE_DREGX_ONCE, 61 | NODE_LIST, 62 | NODE_ARG, 63 | NODE_ARGSCAT, 64 | NODE_ARGSPUSH, 65 | NODE_SPLAT, 66 | NODE_TO_ARY, 67 | NODE_SVALUE, 68 | NODE_BLOCK_ARG, 69 | NODE_DEF, 70 | NODE_SDEF, 71 | NODE_ALIAS, 72 | NODE_UNDEF, 73 | NODE_CLASS, 74 | NODE_MODULE, 75 | NODE_SCLASS, 76 | NODE_COLON2, 77 | NODE_COLON3, 78 | NODE_CREF, 79 | NODE_DOT2, 80 | NODE_DOT3, 81 | NODE_FLIP2, 82 | NODE_FLIP3, 83 | NODE_ATTRSET, 84 | NODE_SELF, 85 | NODE_NIL, 86 | NODE_TRUE, 87 | NODE_FALSE, 88 | NODE_DEFINED, 89 | NODE_NEWLINE, 90 | NODE_POSTEXE, 91 | NODE_ALLOCA, 92 | NODE_DMETHOD, 93 | NODE_BMETHOD, 94 | NODE_MEMO, 95 | NODE_IFUNC, 96 | NODE_DSYM, 97 | NODE_ATTRASGN, 98 | NODE_LAST 99 | }; 100 | 101 | typedef struct RNode { 102 | unsigned long flags; 103 | char *nd_file; 104 | union { 105 | struct RNode *node; 106 | mrb_sym id; 107 | mrb_value value; 108 | //mrb_value (*cfunc)((ARGS_ANY())); 109 | mrb_sym *tbl; 110 | } u1; 111 | union { 112 | struct RNode *node; 113 | mrb_sym id; 114 | long argc; 115 | mrb_value value; 116 | } u2; 117 | union { 118 | struct RNode *node; 119 | mrb_sym id; 120 | long state; 121 | struct global_entry *entry; 122 | long cnt; 123 | mrb_value value; 124 | } u3; 125 | } NODE; 126 | -------------------------------------------------------------------------------- /src/opcode.h: -------------------------------------------------------------------------------- 1 | #ifndef OPCODE_H 2 | #define OPCODE_H 3 | 4 | #define MAXARG_Bx ((1<<16)-1) 5 | #define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */ 6 | 7 | /* instructions OP:A:B:C = 7:9:9:7 (32 bits) */ 8 | /* OP:A:Bx = 7:9:16 */ 9 | /* OP:Ax = 7:25 */ 10 | 11 | #define GET_OPCODE(i) (((mrb_code)(i)) & 0x7f) 12 | #define GETARG_A(i) ((((mrb_code)(i)) >> 23) & 0x1ff) 13 | #define GETARG_B(i) ((((mrb_code)(i)) >> 14) & 0x1ff) 14 | #define GETARG_C(i) ((((mrb_code)(i)) >> 7) & 0x7f) 15 | #define GETARG_Bx(i) ((((mrb_code)(i)) >> 7) & 0xffff) 16 | #define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx) 17 | #define GETARG_Ax(i) ((((mrb_code)(i)) >> 7) & 0x1ffffff) 18 | #define GETARG_UNPACK_b(i,n1,n2) ((((mrb_code)(i)) >> (7+n2)) & (((1<> 7) & (((1<R(A+1) (mSyms[B]=:>,C=1) */ 103 | OP_GE,/* A B C R(A) := R(A)>=R(A+1) (mSyms[B]=:>=,C=1) */ 104 | 105 | OP_ARRAY,/* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */ 106 | OP_ARYCAT,/* A B ary_cat(R(A),R(B)) */ 107 | OP_ARYPUSH,/* A B ary_push(R(A),R(B)) */ 108 | OP_AREF,/* A B C R(A) := R(B)[C] */ 109 | OP_ASET,/* A B C R(B)[C] := R(A) */ 110 | OP_APOST,/* A B C *R(A),R(A+1)..R(A+C) := R(A) */ 111 | 112 | OP_STRING,/* A Bx R(A) := str_dup(Lit(Bx)) */ 113 | OP_STRCAT,/* A B str_cat(R(A),R(B)) */ 114 | 115 | OP_HASH,/* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */ 116 | OP_LAMBDA,/* A Bz Cz R(A) := lambda(SEQ[Bz],Cm) */ 117 | OP_RANGE,/* A B C R(A) := range_new(R(B),R(B+1),C) */ 118 | 119 | OP_OCLASS,/* A R(A) := ::Object */ 120 | OP_CLASS,/* A B R(A) := newclass(R(A),mSym(B),R(A+1)) */ 121 | OP_MODULE,/* A B R(A) := newmodule(R(A),mSym(B)) */ 122 | OP_EXEC,/* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */ 123 | OP_METHOD,/* A B R(A).newmethod(mSym(B),R(A+1)) */ 124 | OP_SCLASS,/* A B R(A) := R(B).singleton_class */ 125 | OP_TCLASS,/* A R(A) := target_class */ 126 | 127 | OP_DEBUG,/* A print R(A) */ 128 | OP_STOP,/* stop VM */ 129 | OP_ERR,/* Bx raise RuntimeError with message Lit(Bx) */ 130 | 131 | OP_RSVD1,/* reserved instruction #1 */ 132 | OP_RSVD2,/* reserved instruction #2 */ 133 | OP_RSVD3,/* reserved instruction #3 */ 134 | OP_RSVD4,/* reserved instruction #4 */ 135 | OP_RSVD5,/* reserved instruction #5 */ 136 | }; 137 | 138 | #define OP_L_STRICT 1 139 | #define OP_L_CAPTURE 2 140 | #define OP_L_METHOD OP_L_STRICT 141 | #define OP_L_LAMBDA (OP_L_STRICT|OP_L_CAPTURE) 142 | #define OP_L_BLOCK OP_L_CAPTURE 143 | 144 | #define OP_R_NORMAL 0 145 | #define OP_R_BREAK 1 146 | #define OP_R_RETURN 2 147 | 148 | #endif /* OPCODE_H */ 149 | -------------------------------------------------------------------------------- /src/pool.c: -------------------------------------------------------------------------------- 1 | #include "pool.h" 2 | #include 3 | 4 | #undef TEST_POOL 5 | #ifdef TEST_POOL 6 | #include 7 | 8 | #define mrb_malloc(m,s) malloc(s) 9 | #define mrb_free(m,p) free(p) 10 | #endif 11 | 12 | #define POOL_PAGE_SIZE 16000 13 | 14 | mrb_pool* 15 | mrb_pool_open(mrb_state *mrb) 16 | { 17 | mrb_pool *pool = mrb_malloc(mrb, sizeof(mrb_pool)); 18 | 19 | if (pool) { 20 | pool->mrb = mrb; 21 | pool->pages = 0; 22 | } 23 | 24 | return pool; 25 | } 26 | 27 | void 28 | mrb_pool_close(mrb_pool *pool) 29 | { 30 | struct mrb_pool_page *page, *tmp; 31 | 32 | if (!pool) return; 33 | page = pool->pages; 34 | while (page) { 35 | tmp = page; 36 | page = page->next; 37 | mrb_free(pool->mrb, tmp); 38 | } 39 | mrb_free(pool->mrb, pool); 40 | } 41 | 42 | static struct mrb_pool_page* 43 | page_alloc(mrb_pool *pool, size_t len) 44 | { 45 | struct mrb_pool_page *page; 46 | 47 | if (len < POOL_PAGE_SIZE) 48 | len = POOL_PAGE_SIZE; 49 | page = mrb_malloc(pool->mrb, sizeof(struct mrb_pool_page)+len-1); 50 | if (page) { 51 | page->offset = 0; 52 | page->len = len; 53 | } 54 | 55 | return page; 56 | } 57 | 58 | void* 59 | mrb_pool_alloc(mrb_pool *pool, size_t len) 60 | { 61 | struct mrb_pool_page *page; 62 | size_t n; 63 | 64 | if (!pool) return 0; 65 | 66 | page = pool->pages; 67 | while (page) { 68 | if (page->offset + len <= page->len) { 69 | n = page->offset; 70 | page->offset += len; 71 | page->last = (void*)page->page+n; 72 | return page->last; 73 | } 74 | page = page->next; 75 | } 76 | page = page_alloc(pool, len); 77 | if (!page) return 0; 78 | page->offset = len; 79 | page->next = pool->pages; 80 | pool->pages = page; 81 | 82 | page->last = (void*)page->page; 83 | return page->last; 84 | } 85 | 86 | int 87 | mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len) 88 | { 89 | struct mrb_pool_page *page; 90 | 91 | if (!pool) return 0; 92 | page = pool->pages; 93 | while (page) { 94 | if (page->last == p) { 95 | size_t beg; 96 | 97 | beg = (char*)p - page->page; 98 | if (beg + len > page->len) return 0; 99 | return 1; 100 | } 101 | page = page->next; 102 | } 103 | return 0; 104 | } 105 | 106 | void* 107 | mrb_pool_realloc(mrb_pool *pool, void *p, size_t oldlen, size_t newlen) 108 | { 109 | struct mrb_pool_page *page; 110 | void *np; 111 | 112 | if (!pool) return 0; 113 | page = pool->pages; 114 | while (page) { 115 | if (page->last == p) { 116 | size_t beg; 117 | 118 | beg = (char*)p - page->page; 119 | if (beg + oldlen != page->offset) break; 120 | if (beg + newlen > page->len) { 121 | page->offset = beg; 122 | break; 123 | } 124 | page->offset = beg + newlen; 125 | return p; 126 | } 127 | page = page->next; 128 | } 129 | np = mrb_pool_alloc(pool, newlen); 130 | memcpy(np, p, oldlen); 131 | return np; 132 | } 133 | 134 | #ifdef TEST_POOL 135 | int 136 | main() 137 | { 138 | int i, len = 250; 139 | mrb_pool *pool; 140 | void *p; 141 | 142 | pool = mrb_pool_open(0); 143 | p = mrb_pool_alloc(pool, len); 144 | for (i=1; i<20; i++) { 145 | printf("%p (len=%d) %d\n", p, len, mrb_pool_can_realloc(pool, p, len*2)); 146 | p = mrb_pool_realloc(pool, p, len, len*2); 147 | len *= 2; 148 | } 149 | mrb_pool_close(pool); 150 | return 0; 151 | } 152 | #endif 153 | -------------------------------------------------------------------------------- /src/pool.h: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include 3 | 4 | typedef struct mrb_pool { 5 | mrb_state *mrb; 6 | struct mrb_pool_page { 7 | struct mrb_pool_page *next; 8 | size_t offset; 9 | size_t len; 10 | void *last; 11 | char page[1]; 12 | } *pages; 13 | } mrb_pool; 14 | 15 | mrb_pool* mrb_pool_open(mrb_state*); 16 | void mrb_pool_close(mrb_pool*); 17 | void* mrb_pool_alloc(mrb_pool*, size_t); 18 | void* mrb_pool_realloc(mrb_pool*, void*, size_t oldlen, size_t newlen); 19 | int mrb_pool_can_realloc(mrb_pool*, void*, size_t); 20 | -------------------------------------------------------------------------------- /src/print.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include "mruby/string.h" 3 | #include 4 | 5 | mrb_value 6 | printstr(mrb_state *mrb, mrb_value obj) 7 | { 8 | struct RString *str; 9 | char *s; 10 | size_t len; 11 | 12 | if (mrb_type(obj) == MRB_TT_STRING) { 13 | str = mrb_str_ptr(obj); 14 | s = str->buf; 15 | len = str->len; 16 | while (len--) { 17 | putc(*s, stdout); 18 | s++; 19 | } 20 | } 21 | return obj; 22 | } 23 | 24 | mrb_value 25 | mrb_p(mrb_state *mrb, mrb_value obj) 26 | { 27 | obj = mrb_funcall(mrb, obj, "inspect", 0); 28 | printstr(mrb, obj); 29 | putc('\n', stdout); 30 | return obj; 31 | } 32 | 33 | /* 15.3.1.2.9 */ 34 | /* 15.3.1.3.34 */ 35 | static mrb_value 36 | p_m(mrb_state *mrb, mrb_value self) 37 | { 38 | int argc, i; 39 | mrb_value *argv; 40 | 41 | mrb_get_args(mrb, "*", &argv, &argc); 42 | for (i=0; ikernel_module; 66 | 67 | mrb_define_method(mrb, krn, "__printstr__", mrb_printstr, ARGS_REQ(1)); 68 | mrb_define_method(mrb, krn, "p", p_m, ARGS_ANY()); /* 15.3.1.3.34 */ 69 | } 70 | -------------------------------------------------------------------------------- /src/proc.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include "mruby/proc.h" 3 | #include "mruby/array.h" 4 | #include "mruby/class.h" 5 | #include "opcode.h" 6 | 7 | struct RProc * 8 | mrb_proc_new(mrb_state *mrb, mrb_irep *irep) 9 | { 10 | struct RProc *p; 11 | 12 | p = mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); 13 | p->body.irep = irep; 14 | p->target_class = (mrb->ci) ? mrb->ci->target_class : 0; 15 | p->env = 0; 16 | 17 | return p; 18 | } 19 | 20 | struct RProc * 21 | mrb_closure_new(mrb_state *mrb, mrb_irep *irep) 22 | { 23 | struct RProc *p = mrb_proc_new(mrb, irep); 24 | struct REnv *e; 25 | 26 | if (!mrb->ci->env) { 27 | e = mrb_obj_alloc(mrb, MRB_TT_ENV, mrb->ci->proc->env); 28 | e->flags= (unsigned int)irep->nlocals; 29 | e->mid = mrb->ci->mid; 30 | e->cioff = mrb->ci - mrb->cibase; 31 | e->stack = mrb->stack; 32 | mrb->ci->env = e; 33 | } 34 | else { 35 | e = mrb->ci->env; 36 | } 37 | p->env = e; 38 | return p; 39 | } 40 | 41 | struct RProc * 42 | mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) 43 | { 44 | struct RProc *p; 45 | 46 | p = mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); 47 | p->body.func = func; 48 | p->flags |= MRB_PROC_CFUNC; 49 | 50 | return p; 51 | } 52 | 53 | int 54 | mrb_proc_cfunc_p(struct RProc *p) 55 | { 56 | return MRB_PROC_CFUNC_P(p); 57 | } 58 | 59 | mrb_value 60 | mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self) 61 | { 62 | return (p->body.func)(mrb, self); 63 | } 64 | 65 | mrb_code* 66 | mrb_proc_iseq(mrb_state *mrb, struct RProc *p) 67 | { 68 | return p->body.irep->iseq; 69 | } 70 | 71 | void 72 | mrb_init_proc(mrb_state *mrb) 73 | { 74 | struct RProc *m; 75 | mrb_code *call_iseq = mrb_malloc(mrb, sizeof(mrb_code)); 76 | mrb_irep *call_irep = mrb_calloc(mrb, sizeof(mrb_irep), 1); 77 | 78 | if ( call_iseq == NULL || call_irep == NULL ) 79 | return; 80 | 81 | *call_iseq = MKOP_A(OP_CALL, 0); 82 | call_irep->idx = -1; 83 | call_irep->flags = MRB_IREP_NOFREE; 84 | call_irep->iseq = call_iseq; 85 | call_irep->ilen = 1; 86 | 87 | mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class); 88 | 89 | m = mrb_proc_new(mrb, call_irep); 90 | mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m); 91 | mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "[]"), m); 92 | } 93 | -------------------------------------------------------------------------------- /src/re.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | re.h - 4 | 5 | **********************************************************************/ 6 | 7 | #ifndef RE_H 8 | #define RE_H 9 | 10 | //#include 11 | #include 12 | 13 | #include "node.h" 14 | #include "regex.h" 15 | #include "encoding.h" 16 | 17 | #define BEG(no) regs->beg[no] 18 | #define END(no) regs->end[no] 19 | 20 | struct rmatch_offset { 21 | long beg; 22 | long end; 23 | }; 24 | 25 | struct rmatch { 26 | struct re_registers regs; 27 | 28 | int char_offset_updated; 29 | int char_offset_num_allocated; 30 | struct rmatch_offset *char_offset; 31 | }; 32 | 33 | //struct RMatch { 34 | // MRUBY_OBJECT_HEADER; 35 | // mrb_value str; 36 | // struct re_registers *regs; 37 | //}; 38 | struct RMatch { 39 | MRUBY_OBJECT_HEADER; 40 | mrb_value str; 41 | struct rmatch *rmatch; 42 | mrb_value regexp; /* RRegexp */ 43 | }; 44 | 45 | struct RRegexp { 46 | MRUBY_OBJECT_HEADER; 47 | struct re_pattern_buffer *ptr; 48 | mrb_value src; 49 | unsigned long usecnt; 50 | }; 51 | 52 | #define mrb_regex_ptr(r) ((struct RRegexp*)((r).value.p)) 53 | #define RREGEXP(r) ((struct RRegexp*)((r).value.p)) 54 | #define RREGEXP_SRC(r) (RREGEXP(r)->src) 55 | #define RREGEXP_SRC_PTR(r) (((struct RString*)(RREGEXP_SRC(r).value.p))->buf) 56 | #define RREGEXP_SRC_LEN(r) RSTRING_LEN(RREGEXP(r)->src) 57 | int re_adjust_startpos(struct re_pattern_buffer *bufp, const char *string, int size, int startpos, int range); 58 | 59 | typedef struct re_pattern_buffer Regexp; 60 | 61 | //#define RMATCH(obj) (R_CAST(RMatch)(obj)) 62 | #define RMATCH_REGS(v) (&((struct RMatch*)((v).value.p))->rmatch->regs) 63 | #define RMATCH(v) ((struct RMatch*)((v).value.p)) 64 | #define mrb_match_ptr(v) ((struct RMatch*)((v).value.p)) 65 | 66 | int mrb_memcmp(const void *p1, const void *p2, int len); 67 | 68 | mrb_int mrb_reg_search (mrb_state *mrb, mrb_value, mrb_value, mrb_int, mrb_int); 69 | mrb_value mrb_reg_regsub (mrb_state *mrb, mrb_value, mrb_value, struct re_registers *, mrb_value); 70 | //mrb_value mrb_reg_regsub(mrb_value, mrb_value, struct re_registers *, mrb_value); 71 | mrb_int mrb_reg_adjust_startpos(mrb_state *mrb, mrb_value re, mrb_value str, mrb_int pos, mrb_int reverse); 72 | void mrb_match_busy (mrb_value); 73 | 74 | mrb_value mrb_reg_quote(mrb_state *mrb, mrb_value str); 75 | mrb_value mrb_reg_regcomp(mrb_state *mrb, mrb_value str); 76 | mrb_value mrb_reg_match_str(mrb_state *mrb, mrb_value re, mrb_value str); 77 | mrb_value mrb_reg_nth_match(mrb_state *mrb, mrb_int nth, mrb_value match); 78 | mrb_value mrb_backref_get(mrb_state *mrb); 79 | //mrb_int mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n); 80 | mrb_value mrb_reg_to_s(mrb_state *mrb, mrb_value re); 81 | void mrb_backref_set(mrb_state *mrb, mrb_value val); 82 | mrb_value match_alloc(mrb_state *mrb); 83 | int mrb_reg_backref_number(mrb_state *mrb, mrb_value match, mrb_value backref); 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/regenc.h: -------------------------------------------------------------------------------- 1 | #ifndef ONIGURUMA_REGENC_H 2 | #define ONIGURUMA_REGENC_H 3 | /********************************************************************** 4 | regenc.h - Oniguruma (regular expression library) 5 | **********************************************************************/ 6 | /*- 7 | * Copyright (c) 2002-2008 K.Kosako 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | * SUCH DAMAGE. 30 | */ 31 | 32 | #include 33 | #include 34 | #define RUBY 35 | 36 | #ifndef mrb_compile_warn 37 | #define mrb_compile_warn(a,b,c,d) printf(c,d) 38 | #endif 39 | 40 | #ifndef REGINT_H 41 | #ifdef ONIG_ESCAPE_UCHAR_COLLISION 42 | #undef ONIG_ESCAPE_UCHAR_COLLISION 43 | #endif 44 | #endif 45 | #include "oniguruma.h" 46 | 47 | typedef struct { 48 | OnigCodePoint from; 49 | OnigCodePoint to; 50 | } OnigPairCaseFoldCodes; 51 | 52 | 53 | #ifndef ARG_UNUSED 54 | #if defined(__GNUC__) 55 | # define ARG_UNUSED __attribute__ ((unused)) 56 | #else 57 | # define ARG_UNUSED 58 | #endif 59 | #endif 60 | 61 | #define ONIG_IS_NULL(p) (((void*)(p)) == (void*)0) 62 | #define ONIG_IS_NOT_NULL(p) (((void*)(p)) != (void*)0) 63 | #define ONIG_CHECK_NULL_RETURN(p) if (ONIG_IS_NULL(p)) return NULL 64 | #define ONIG_CHECK_NULL_RETURN_VAL(p,val) if (ONIG_IS_NULL(p)) return (val) 65 | 66 | #define enclen(enc,p,e) ((enc->max_enc_len == enc->min_enc_len) ? enc->min_enc_len : ONIGENC_MBC_ENC_LEN(enc,p,e)) 67 | 68 | /* character types bit flag */ 69 | #define BIT_CTYPE_NEWLINE (1<< ONIGENC_CTYPE_NEWLINE) 70 | #define BIT_CTYPE_ALPHA (1<< ONIGENC_CTYPE_ALPHA) 71 | #define BIT_CTYPE_BLANK (1<< ONIGENC_CTYPE_BLANK) 72 | #define BIT_CTYPE_CNTRL (1<< ONIGENC_CTYPE_CNTRL) 73 | #define BIT_CTYPE_DIGIT (1<< ONIGENC_CTYPE_DIGIT) 74 | #define BIT_CTYPE_GRAPH (1<< ONIGENC_CTYPE_GRAPH) 75 | #define BIT_CTYPE_LOWER (1<< ONIGENC_CTYPE_LOWER) 76 | #define BIT_CTYPE_PRINT (1<< ONIGENC_CTYPE_PRINT) 77 | #define BIT_CTYPE_PUNCT (1<< ONIGENC_CTYPE_PUNCT) 78 | #define BIT_CTYPE_SPACE (1<< ONIGENC_CTYPE_SPACE) 79 | #define BIT_CTYPE_UPPER (1<< ONIGENC_CTYPE_UPPER) 80 | #define BIT_CTYPE_XDIGIT (1<< ONIGENC_CTYPE_XDIGIT) 81 | #define BIT_CTYPE_WORD (1<< ONIGENC_CTYPE_WORD) 82 | #define BIT_CTYPE_ALNUM (1<< ONIGENC_CTYPE_ALNUM) 83 | #define BIT_CTYPE_ASCII (1<< ONIGENC_CTYPE_ASCII) 84 | 85 | #define CTYPE_TO_BIT(ctype) (1<<(ctype)) 86 | #define CTYPE_IS_WORD_GRAPH_PRINT(ctype) \ 87 | ((ctype) == ONIGENC_CTYPE_WORD || (ctype) == ONIGENC_CTYPE_GRAPH ||\ 88 | (ctype) == ONIGENC_CTYPE_PRINT) 89 | 90 | 91 | typedef struct { 92 | const UChar *name; 93 | int ctype; 94 | short int len; 95 | } PosixBracketEntryType; 96 | 97 | #define PosixBracketEntryInit(name, ctype) {(const UChar *)name, ctype, (short int)(sizeof(name) - 1)} 98 | 99 | /* #define USE_CRNL_AS_LINE_TERMINATOR */ 100 | #define USE_UNICODE_PROPERTIES 101 | /* #define USE_UNICODE_CASE_FOLD_TURKISH_AZERI */ 102 | /* #define USE_UNICODE_ALL_LINE_TERMINATORS */ /* see Unicode.org UTF#18 */ 103 | 104 | 105 | #define ONIG_ENCODING_INIT_DEFAULT ONIG_ENCODING_ASCII 106 | 107 | /* for encoding system implementation (internal) */ 108 | ONIG_EXTERN int onigenc_ascii_apply_all_case_fold(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg, OnigEncoding enc); 109 | ONIG_EXTERN int onigenc_ascii_get_case_fold_codes_by_str(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[], OnigEncoding enc); 110 | ONIG_EXTERN int onigenc_apply_all_case_fold_with_map(int map_size, const OnigPairCaseFoldCodes map[], int ess_tsett_flag, OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg); 111 | ONIG_EXTERN int onigenc_get_case_fold_codes_by_str_with_map(int map_size, const OnigPairCaseFoldCodes map[], int ess_tsett_flag, OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[]); 112 | ONIG_EXTERN int onigenc_not_support_get_ctype_code_range(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[], OnigEncoding enc); 113 | ONIG_EXTERN int onigenc_is_mbc_newline_0x0a(const UChar* p, const UChar* end, OnigEncoding enc); 114 | 115 | /* methods for single byte encoding */ 116 | ONIG_EXTERN int onigenc_ascii_mbc_case_fold(OnigCaseFoldType flag, const UChar** p, const UChar* end, UChar* lower, OnigEncoding enc); 117 | ONIG_EXTERN int onigenc_single_byte_mbc_enc_len(const UChar* p, const UChar* e, OnigEncoding enc); 118 | ONIG_EXTERN OnigCodePoint onigenc_single_byte_mbc_to_code(const UChar* p, const UChar* end, OnigEncoding enc); 119 | ONIG_EXTERN int onigenc_single_byte_code_to_mbclen(OnigCodePoint code, OnigEncoding enc); 120 | ONIG_EXTERN int onigenc_single_byte_code_to_mbc(OnigCodePoint code, UChar *buf, OnigEncoding enc); 121 | ONIG_EXTERN UChar* onigenc_single_byte_left_adjust_char_head(const UChar* start, const UChar* s, const OnigUChar* end, OnigEncoding enc); 122 | ONIG_EXTERN int onigenc_always_true_is_allowed_reverse_match(const UChar* s, const UChar* end, OnigEncoding enc); 123 | ONIG_EXTERN int onigenc_always_false_is_allowed_reverse_match(const UChar* s, const UChar* end, OnigEncoding enc); 124 | ONIG_EXTERN int onigenc_ascii_is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc); 125 | 126 | /* methods for multi byte encoding */ 127 | ONIG_EXTERN OnigCodePoint onigenc_mbn_mbc_to_code(OnigEncoding enc, const UChar* p, const UChar* end); 128 | ONIG_EXTERN int onigenc_mbn_mbc_case_fold(OnigEncoding enc, OnigCaseFoldType flag, const UChar** p, const UChar* end, UChar* lower); 129 | ONIG_EXTERN int onigenc_mb2_code_to_mbclen(OnigCodePoint code, OnigEncoding enc); 130 | ONIG_EXTERN int onigenc_mb2_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf); 131 | ONIG_EXTERN int onigenc_minimum_property_name_to_ctype(OnigEncoding enc, UChar* p, UChar* end); 132 | ONIG_EXTERN int onigenc_unicode_property_name_to_ctype(OnigEncoding enc, UChar* p, UChar* end); 133 | ONIG_EXTERN int onigenc_mb2_is_code_ctype(OnigEncoding enc, OnigCodePoint code, unsigned int ctype); 134 | ONIG_EXTERN int onigenc_mb4_code_to_mbclen(OnigCodePoint code, OnigEncoding enc); 135 | ONIG_EXTERN int onigenc_mb4_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf); 136 | ONIG_EXTERN int onigenc_mb4_is_code_ctype(OnigEncoding enc, OnigCodePoint code, unsigned int ctype); 137 | 138 | 139 | /* in enc/unicode.c */ 140 | ONIG_EXTERN int onigenc_unicode_is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc); 141 | ONIG_EXTERN int onigenc_utf16_32_get_ctype_code_range(OnigCtype ctype, OnigCodePoint *sb_out, const OnigCodePoint* ranges[], OnigEncoding enc); 142 | ONIG_EXTERN int onigenc_unicode_ctype_code_range(int ctype, const OnigCodePoint* ranges[]); 143 | ONIG_EXTERN int onigenc_unicode_get_case_fold_codes_by_str(OnigEncoding enc, OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[]); 144 | ONIG_EXTERN int onigenc_unicode_mbc_case_fold(OnigEncoding enc, OnigCaseFoldType flag, const UChar** pp, const UChar* end, UChar* fold); 145 | ONIG_EXTERN int onigenc_unicode_apply_all_case_fold(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg, OnigEncoding enc); 146 | 147 | 148 | #define UTF16_IS_SURROGATE_FIRST(c) (((c) & 0xfc) == 0xd8) 149 | #define UTF16_IS_SURROGATE_SECOND(c) (((c) & 0xfc) == 0xdc) 150 | 151 | #define ONIGENC_ISO_8859_1_TO_LOWER_CASE(c) \ 152 | OnigEncISO_8859_1_ToLowerCaseTable[c] 153 | #define ONIGENC_ISO_8859_1_TO_UPPER_CASE(c) \ 154 | OnigEncISO_8859_1_ToUpperCaseTable[c] 155 | 156 | ONIG_EXTERN const UChar OnigEncISO_8859_1_ToLowerCaseTable[]; 157 | ONIG_EXTERN const UChar OnigEncISO_8859_1_ToUpperCaseTable[]; 158 | 159 | ONIG_EXTERN int 160 | onigenc_with_ascii_strncmp(OnigEncoding enc, const UChar* p, const UChar* end, const UChar* sascii /* ascii */, int n); 161 | ONIG_EXTERN UChar* 162 | onigenc_step(OnigEncoding enc, const UChar* p, const UChar* end, int n); 163 | 164 | /* defined in regexec.c, but used in enc/xxx.c */ 165 | extern int onig_is_in_code_range (const UChar* p, OnigCodePoint code); 166 | 167 | ONIG_EXTERN OnigEncoding OnigEncDefaultCharEncoding; 168 | ONIG_EXTERN const UChar OnigEncAsciiToLowerCaseTable[]; 169 | ONIG_EXTERN const UChar OnigEncAsciiToUpperCaseTable[]; 170 | ONIG_EXTERN const unsigned short OnigEncAsciiCtypeTable[]; 171 | 172 | #define ONIGENC_IS_ASCII_CODE(code) ((code) < 0x80) 173 | #define ONIGENC_ASCII_CODE_TO_LOWER_CASE(c) OnigEncAsciiToLowerCaseTable[c] 174 | #define ONIGENC_ASCII_CODE_TO_UPPER_CASE(c) OnigEncAsciiToUpperCaseTable[c] 175 | #define ONIGENC_IS_ASCII_CODE_CTYPE(code,ctype) \ 176 | ((OnigEncAsciiCtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0) 177 | #define ONIGENC_IS_ASCII_CODE_CASE_AMBIG(code) \ 178 | (ONIGENC_IS_ASCII_CODE_CTYPE(code, ONIGENC_CTYPE_UPPER) ||\ 179 | ONIGENC_IS_ASCII_CODE_CTYPE(code, ONIGENC_CTYPE_LOWER)) 180 | 181 | #ifdef ONIG_ENC_REGISTER 182 | extern int ONIG_ENC_REGISTER(const char *, OnigEncodingType*); 183 | #define OnigEncodingName(n) encoding_##n 184 | #define OnigEncodingDeclare(n) static OnigEncodingType OnigEncodingName(n) 185 | #define OnigEncodingDefine(f,n) \ 186 | OnigEncodingDeclare(n); \ 187 | void Init_##f(void) { \ 188 | ONIG_ENC_REGISTER(OnigEncodingName(n).name, \ 189 | &OnigEncodingName(n)); \ 190 | } \ 191 | OnigEncodingDeclare(n) 192 | #else 193 | #define OnigEncodingName(n) OnigEncoding##n 194 | #define OnigEncodingDeclare(n) OnigEncodingType OnigEncodingName(n) 195 | #define OnigEncodingDefine(f,n) OnigEncodingDeclare(n) 196 | #endif 197 | 198 | /* macros for define replica encoding and encoding alias */ 199 | #define ENC_REPLICATE(name, orig) 200 | #define ENC_ALIAS(name, orig) 201 | #define ENC_DUMMY(name) 202 | 203 | #endif /* ONIGURUMA_REGENC_H */ 204 | -------------------------------------------------------------------------------- /src/regex.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | regex.h - 4 | 5 | $Author: akr $ 6 | 7 | Copyright (C) 1993-2007 Yukihiro Matsumoto 8 | 9 | **********************************************************************/ 10 | 11 | #ifndef ONIGURUMA_REGEX_H 12 | #define ONIGURUMA_REGEX_H 1 13 | 14 | #if defined(__cplusplus) 15 | extern "C" { 16 | #endif 17 | 18 | #include "oniguruma.h" 19 | 20 | #ifndef ONIG_RUBY_M17N 21 | 22 | ONIG_EXTERN OnigEncoding OnigEncDefaultCharEncoding; 23 | 24 | #define mbclen(p,e,enc) mrb_enc_mbclen((p),(e),(enc)) 25 | 26 | #endif /* ifndef ONIG_RUBY_M17N */ 27 | 28 | #if defined(__cplusplus) 29 | } /* extern "C" { */ 30 | #endif 31 | 32 | #endif /* ONIGURUMA_REGEX_H */ 33 | -------------------------------------------------------------------------------- /src/ritehash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Rite Hash 3 | * 4 | * 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | typedef uint32_t khint_t; 11 | typedef khint_t khiter_t; 12 | 13 | #define INITIAL_HASH_SIZE 32 14 | #define UPPER_BOUND(x) ((x)>>2|(x>>1)) 15 | 16 | //extern uint8_t __m[]; 17 | 18 | /* mask for flags */ 19 | static uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; 20 | 21 | 22 | #define __ac_isempty(e_flag, d_flag, i) (e_flag[(i)/8]&__m[(i)%8]) 23 | #define __ac_isdel(e_flag, d_flag, i) (d_flag[(i)/8]&__m[(i)%8]) 24 | #define __ac_iseither(e_flag, d_flag, i) (__ac_isempty(e_flag,d_flag,i)||__ac_isdel(e_flag,d_flag,i)) 25 | 26 | 27 | /* struct kh_xxx 28 | 29 | name: ash name 30 | khkey_t: key data type 31 | khval_t: value data type 32 | kh_is_map: (not implemented / not used in RiteVM ) 33 | __hash_func: hash function 34 | __hash_equal: hash comparation function 35 | */ 36 | #define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ 37 | typedef struct kh_##name { \ 38 | khint_t n_buckets; \ 39 | khint_t size; \ 40 | khint_t n_occupied; \ 41 | khint_t upper_bound; \ 42 | uint8_t *e_flags; \ 43 | uint8_t *d_flags; \ 44 | khkey_t *keys; \ 45 | khval_t *vals; \ 46 | khint_t mask; \ 47 | khint_t inc; \ 48 | mrb_state *mrb; \ 49 | } kh_##name##_t; \ 50 | static void kh_alloc_##name(kh_##name##_t *h) \ 51 | { \ 52 | khint_t sz = h->n_buckets; \ 53 | h->size = h->n_occupied = 0; \ 54 | h->upper_bound = UPPER_BOUND(sz); \ 55 | h->e_flags = (uint8_t *)mrb_malloc(h->mrb, sizeof(uint8_t)*sz/4); \ 56 | h->d_flags = h->e_flags + sz/8; \ 57 | memset(h->e_flags, 0xff, sz/8*sizeof(uint8_t)); \ 58 | memset(h->d_flags, 0x00, sz/8*sizeof(uint8_t)); \ 59 | h->keys = (khkey_t *)mrb_malloc(h->mrb, sizeof(khkey_t)*sz); \ 60 | h->vals = (khval_t *)mrb_malloc(h->mrb, sizeof(khval_t)*sz); \ 61 | h->mask = sz-1; \ 62 | h->inc = sz/2-1; \ 63 | } \ 64 | static inline kh_##name##_t *kh_init_##name(mrb_state *mrb){ \ 65 | kh_##name##_t *h = (kh_##name##_t*)mrb_calloc(mrb, 1, sizeof(kh_##name##_t)); \ 66 | h->n_buckets = INITIAL_HASH_SIZE; \ 67 | h->mrb = mrb; \ 68 | kh_alloc_##name(h); \ 69 | return h; \ 70 | } \ 71 | static inline void kh_destroy_##name(kh_##name##_t *h) \ 72 | { \ 73 | if( h ){ \ 74 | mrb_free(h->mrb, h->keys); \ 75 | mrb_free(h->mrb, h->vals); \ 76 | mrb_free(h->mrb, h->e_flags); \ 77 | mrb_free(h->mrb, h); \ 78 | } \ 79 | } \ 80 | static inline void kh_clear_##name(kh_##name##_t *h) \ 81 | { \ 82 | if( h && h->e_flags ){ \ 83 | memset(h->e_flags, 0xff, h->n_buckets/8*sizeof(uint8_t)); \ 84 | memset(h->d_flags, 0x00, h->n_buckets/8*sizeof(uint8_t)); \ 85 | h->size = h->n_occupied = 0; \ 86 | } \ 87 | } \ 88 | static inline khint_t kh_get_##name(kh_##name##_t *h, khkey_t key) \ 89 | { \ 90 | khint_t k = __hash_func(h->mrb,key) & (h->mask); \ 91 | while( !__ac_isempty(h->e_flags, h->d_flags, k) ){ \ 92 | if( !__ac_isdel(h->e_flags, h->d_flags, k) ){ \ 93 | if( __hash_equal(h->mrb,h->keys[k], key) ) return k; \ 94 | } \ 95 | k = (k+h->inc) & (h->mask); \ 96 | } \ 97 | return h->n_buckets; \ 98 | } \ 99 | static inline khint_t kh_put_##name(kh_##name##_t *h, khkey_t key); \ 100 | static void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ 101 | { \ 102 | if( new_n_bucketse_flags; \ 110 | uint8_t *old_d_flags = h->d_flags; \ 111 | khkey_t *old_keys = h->keys; \ 112 | khval_t *old_vals = h->vals; \ 113 | khint_t old_n_buckets = h->n_buckets; \ 114 | h->n_buckets = new_n_buckets; \ 115 | kh_alloc_##name(h); \ 116 | /* relocate */ \ 117 | khint_t i; \ 118 | for( i=0 ; in_occupied >= h->upper_bound ){ \ 129 | kh_resize_##name(h, h->n_buckets*2); \ 130 | } \ 131 | k = __hash_func(h->mrb,key) & (h->mask); \ 132 | while( !__ac_iseither(h->e_flags, h->d_flags, k) ){ \ 133 | if( __hash_equal(h->mrb,h->keys[k], key) ) break; \ 134 | k = (k+h->inc) & (h->mask); \ 135 | } \ 136 | if( __ac_isempty(h->e_flags, h->d_flags, k) ) { \ 137 | /* put at empty */ \ 138 | h->keys[k] = key; \ 139 | h->e_flags[k/8] &= ~__m[k%8]; \ 140 | h->size++; \ 141 | h->n_occupied++; \ 142 | } else if( __ac_isdel(h->e_flags, h->d_flags, k) ) { \ 143 | /* put at del */ \ 144 | h->keys[k] = key; \ 145 | h->d_flags[k/8] &= ~__m[k%8]; \ 146 | h->size++; \ 147 | } \ 148 | return k; \ 149 | } \ 150 | static inline void kh_del_##name(kh_##name##_t *h, khint_t x) \ 151 | { \ 152 | h->d_flags[x/8] |= __m[x%8]; \ 153 | h->size--; \ 154 | } \ 155 | static inline void kh_debug_##name(kh_##name##_t *h) \ 156 | { \ 157 | khint_t i; \ 158 | printf("idx:e_flag:d_flag\n"); \ 159 | for( i=0 ; in_buckets/8 ; i++ ){ \ 160 | printf("%4d:%02X:%02X\n", i, h->e_flags[i], h->d_flags[i]); \ 161 | } \ 162 | } \ 163 | 164 | #define khash_t(name) kh_##name##_t 165 | 166 | #define kh_init(name,mrb) kh_init_##name(mrb) 167 | #define kh_destroy(name, h) kh_destroy_##name(h) 168 | #define kh_clear(name, h) kh_clear_##name(h) 169 | #define kh_resize(name, h, s) kh_resize_##name(h, s) 170 | #define kh_put(name, h, k, r) kh_put_##name(h, k) 171 | #define kh_get(name, h, k) kh_get_##name(h, k) 172 | #define kh_del(name, h, k) kh_del_##name(h, k) 173 | #define kh_debug(name, h) kh_debug_##name(h) 174 | 175 | #define kh_exist(h, x) (!__ac_iseither((h)->e_flags, (h)->d_flags, (x))) 176 | #define kh_key(h, x) ((h)->keys[x]) 177 | #define kh_val(h, x) ((h)->vals[x]) 178 | #define kh_value(h, x) ((h)->vals[x]) 179 | #define kh_begin(h) (khint_t)(0) 180 | #define kh_end(h) ((h)->n_buckets) 181 | #define kh_size(h) ((h)->size) 182 | #define kh_n_buckets(h) ((h)->n_buckets) 183 | 184 | //#define kh_int_hash_func(mrb,key) (uint32_t)(key) 185 | #define kh_int_hash_func(mrb,key) (uint32_t)((key)^((key)<<2)^((key)>>2)) 186 | #define kh_int_hash_equal(mrb,a, b) (a == b) 187 | #define kh_int64_hash_func(mrb,key) (uint32_t)((key)>>33^(key)^(key)<<11) 188 | #define kh_int64_hash_equal(mrb,a, b) (a == b) 189 | static inline khint_t __ac_X31_hash_string(const char *s) 190 | { 191 | khint_t h = *s; 192 | if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s; 193 | return h; 194 | } 195 | #define kh_str_hash_func(mrb,key) __ac_X31_hash_string(key) 196 | #define kh_str_hash_equal(mrb,a, b) (strcmp(a, b) == 0) 197 | 198 | #define KHASH_MAP_INIT_INT(name, khval_t) \ 199 | KHASH_INIT(name, uint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) 200 | typedef const char *kh_cstr_t; 201 | #define KHASH_MAP_INIT_STR(name, khval_t) \ 202 | KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) 203 | 204 | -------------------------------------------------------------------------------- /src/st.h: -------------------------------------------------------------------------------- 1 | /* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */ 2 | 3 | /* @(#) st.h 5.1 89/12/14 */ 4 | 5 | #ifndef RUBY_ST_H 6 | #define RUBY_ST_H 1 7 | 8 | #if defined(__cplusplus) 9 | extern "C" { 10 | #endif 11 | 12 | #ifndef RUBY_LIB_PREFIX 13 | 14 | #ifdef RUBY_EXTCONF_H 15 | #include RUBY_EXTCONF_H 16 | #endif 17 | #endif 18 | 19 | #if defined STDC_HEADERS 20 | #include 21 | #elif defined HAVE_STDLIB_H 22 | #include 23 | #endif 24 | 25 | #ifdef HAVE_STDINT_H 26 | # include 27 | #endif 28 | #include 29 | 30 | #ifndef CHAR_BIT 31 | # ifdef HAVE_LIMITS_H 32 | # include 33 | # else 34 | # define CHAR_BIT 8 35 | # endif 36 | #endif 37 | 38 | #ifndef _ 39 | # define _(args) args 40 | #endif 41 | 42 | #ifndef ANYARGS 43 | # ifdef __cplusplus 44 | # define ANYARGS ... 45 | # else 46 | # define ANYARGS 47 | # endif 48 | #endif 49 | 50 | typedef uintptr_t st_data_t; 51 | typedef struct st_table st_table; 52 | 53 | typedef st_data_t st_index_t; 54 | typedef int st_compare_func(st_data_t, st_data_t); 55 | typedef st_index_t st_hash_func(st_data_t); 56 | 57 | typedef struct st_table_entry st_table_entry; 58 | 59 | struct st_table_entry { 60 | st_index_t hash; 61 | st_data_t key; 62 | st_data_t record; 63 | st_table_entry *next; 64 | st_table_entry *fore, *back; 65 | }; 66 | 67 | #ifndef SIZEOF_VOIDP 68 | #define SIZEOF_VOIDP 4 69 | #endif 70 | 71 | #define SIZEOF_ST_INDEX_T SIZEOF_VOIDP 72 | 73 | struct st_hash_type { 74 | int (*compare)(ANYARGS /*st_data_t, st_data_t*/); /* st_compare_func* */ 75 | st_index_t (*hash)(ANYARGS /*st_data_t*/); /* st_hash_func* */ 76 | }; 77 | 78 | #define ST_INDEX_BITS (sizeof(st_index_t) * CHAR_BIT) 79 | 80 | struct st_table { 81 | const struct st_hash_type *type; 82 | st_index_t num_bins; 83 | unsigned int entries_packed : 1; 84 | #ifdef __GNUC__ 85 | __extension__ 86 | #endif 87 | st_index_t num_entries : ST_INDEX_BITS - 1; 88 | struct st_table_entry **bins; 89 | struct st_table_entry *head, *tail; 90 | }; 91 | 92 | #define st_is_member(table,key) st_lookup(table,key,(st_data_t *)0) 93 | 94 | enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK}; 95 | 96 | st_table *st_init_table(const struct st_hash_type *); 97 | st_table *st_init_table_with_size(const struct st_hash_type *, st_index_t); 98 | st_table *st_init_numtable(void); 99 | st_table *st_init_numtable_with_size(st_index_t); 100 | st_table *st_init_strtable(void); 101 | st_table *st_init_strtable_with_size(st_index_t); 102 | st_table *st_init_strcasetable(void); 103 | st_table *st_init_strcasetable_with_size(st_index_t); 104 | int st_delete(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */ 105 | int st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t); 106 | int st_insert(st_table *, st_data_t, st_data_t); 107 | int st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t)); 108 | int st_lookup(st_table *, st_data_t, st_data_t *); 109 | int st_get_key(st_table *, st_data_t, st_data_t *); 110 | int st_foreach(st_table *, int (*)(ANYARGS), st_data_t); 111 | int st_foreachNew(mrb_state *mrb, st_table *, int (*)(ANYARGS), void*); 112 | int st_reverse_foreach(st_table *, int (*)(ANYARGS), st_data_t); 113 | void st_add_direct(st_table *, st_data_t, st_data_t); 114 | void st_free_table(st_table *); 115 | void st_cleanup_safe(st_table *, st_data_t); 116 | void st_clear(st_table *); 117 | st_table *st_copy(st_table *); 118 | int st_numcmp(st_data_t, st_data_t); 119 | st_index_t st_numhash(st_data_t); 120 | int st_strcasecmp(const char *s1, const char *s2); 121 | int st_strncasecmp(const char *s1, const char *s2, size_t n); 122 | size_t st_memsize(const st_table *); 123 | st_index_t st_hash(const void *ptr, size_t len, st_index_t h); 124 | st_index_t st_hash_uint32(st_index_t h, uint32_t i); 125 | st_index_t st_hash_uint(st_index_t h, st_index_t i); 126 | st_index_t st_hash_end(st_index_t h); 127 | st_index_t st_hash_start(st_index_t h); 128 | #define st_hash_start(h) ((st_index_t)(h)) 129 | 130 | int st_strcasecmp(const char *s1, const char *s2); 131 | int st_strncasecmp(const char *s1, const char *s2, size_t n); 132 | #define STRCASECMP(s1, s2) (st_strcasecmp(s1, s2)) 133 | #define STRNCASECMP(s1, s2, n) (st_strncasecmp(s1, s2, n)) 134 | 135 | #if defined(__cplusplus) 136 | } /* extern "C" { */ 137 | #endif 138 | 139 | #endif /* RUBY_ST_H */ 140 | -------------------------------------------------------------------------------- /src/state.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include "irep.h" 3 | #include 4 | 5 | void mrb_init_heap(mrb_state*); 6 | void mrb_init_core(mrb_state*); 7 | void mrb_init_ext(mrb_state*); 8 | 9 | mrb_state* 10 | mrb_open_allocf(mrb_allocf f) 11 | { 12 | mrb_state *mrb = (f)(NULL, NULL, sizeof(mrb_state)); 13 | 14 | memset(mrb, 0, sizeof(mrb_state)); 15 | mrb->allocf = f; 16 | mrb->current_white_part = MRB_GC_WHITE_A; 17 | 18 | mrb_init_heap(mrb); 19 | mrb_init_core(mrb); 20 | mrb_init_ext(mrb); 21 | return mrb; 22 | } 23 | 24 | static void* 25 | allocf(mrb_state *mrb, void *p, size_t size) 26 | { 27 | if (size == 0) { 28 | free(p); 29 | return NULL; 30 | } 31 | else { 32 | return realloc(p, size); 33 | } 34 | } 35 | 36 | mrb_state* 37 | mrb_open() 38 | { 39 | mrb_state *mrb = mrb_open_allocf(allocf); 40 | 41 | return mrb; 42 | } 43 | 44 | void 45 | mrb_close(mrb_state *mrb) 46 | { 47 | int i; 48 | 49 | /* free */ 50 | mrb_free(mrb, mrb->stbase); 51 | mrb_free(mrb, mrb->cibase); 52 | for (i=0; iirep_len; i++) { 53 | if (mrb->irep[i]->flags & MRB_IREP_NOFREE) continue; 54 | if ((mrb->irep[i]->flags & MRB_ISEQ_NOFREE) == 0) { 55 | mrb_free(mrb, mrb->irep[i]->iseq); 56 | } 57 | mrb_free(mrb, mrb->irep[i]->pool); 58 | mrb_free(mrb, mrb->irep[i]->syms); 59 | mrb_free(mrb, mrb->irep[i]); 60 | } 61 | mrb_free(mrb, mrb->irep); 62 | mrb_free(mrb, mrb); 63 | } 64 | 65 | void 66 | mrb_add_irep(mrb_state *mrb, int idx) 67 | { 68 | if (!mrb->irep) { 69 | int max = 256; 70 | 71 | if (idx > max) max = idx+1; 72 | mrb->irep = mrb_malloc(mrb, sizeof(mrb_irep*)*max); 73 | mrb->irep_capa = max; 74 | } 75 | else if (mrb->irep_capa < idx) { 76 | while (mrb->irep_capa < idx) { 77 | mrb->irep_capa *= 2; 78 | } 79 | mrb->irep = mrb_realloc(mrb, mrb->irep, sizeof(mrb_irep)*mrb->irep_capa); 80 | } 81 | } 82 | 83 | mrb_value 84 | mrb_top_self(mrb_state *mrb) 85 | { 86 | // for now 87 | return mrb_nil_value(); 88 | } 89 | -------------------------------------------------------------------------------- /src/symbol.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include "ritehash.h" 3 | #include 4 | 5 | #include 6 | #include 7 | #include "mruby/string.h" 8 | #include 9 | #include "mruby/class.h" 10 | #include "variable.h" 11 | #include 12 | 13 | #ifdef INCLUDE_REGEXP 14 | #include "re.h" 15 | #include "regex.h" 16 | #include "st.h" 17 | #endif 18 | 19 | /* ------------------------------------------------------ */ 20 | KHASH_MAP_INIT_INT(s2n, const char*); 21 | KHASH_MAP_INIT_STR(n2s, mrb_sym); 22 | /* ------------------------------------------------------ */ 23 | mrb_sym 24 | mrb_intern(mrb_state *mrb, const char *name) 25 | { 26 | khash_t(n2s) *h = mrb->name2sym; 27 | khash_t(s2n) *rh = mrb->sym2name; 28 | khiter_t k; 29 | int r; 30 | size_t len; 31 | char *p; 32 | mrb_sym sym; 33 | 34 | k = kh_get(n2s, h, name); 35 | if (k != kh_end(h)) 36 | return kh_value(h, k); 37 | 38 | sym = ++mrb->symidx; 39 | len = strlen(name); 40 | p = mrb_malloc(mrb, len+1); 41 | memcpy(p, name, len); 42 | p[len] = 0; 43 | k = kh_put(n2s, h, p, &r); 44 | kh_value(h, k) = sym; 45 | 46 | k = kh_put(s2n, rh, sym, &r); 47 | kh_value(rh, k) = p; 48 | 49 | return sym; 50 | } 51 | 52 | const char* 53 | mrb_sym2name(mrb_state *mrb, mrb_sym sym) 54 | { 55 | khash_t(s2n) *h = mrb->sym2name; 56 | khiter_t k; 57 | 58 | k = kh_get(s2n, h, sym); 59 | if (k == kh_end(h)) { 60 | return NULL; /* missing */ 61 | } 62 | return kh_value(h, k); 63 | } 64 | 65 | void 66 | mrb_free_symtbls(mrb_state *mrb) 67 | { 68 | khash_t(s2n) *h = mrb->sym2name; 69 | khiter_t k; 70 | 71 | for (k = kh_begin(h); k != kh_end(h); ++k) 72 | if (kh_exist(h, k)) mrb_free(mrb, (char*)kh_value(h, k)); 73 | kh_destroy(s2n,mrb->sym2name); 74 | kh_destroy(n2s,mrb->name2sym); 75 | } 76 | 77 | void 78 | mrb_init_symtbl(mrb_state *mrb) 79 | { 80 | mrb->name2sym = kh_init(n2s, mrb); 81 | mrb->sym2name = kh_init(s2n, mrb); 82 | } 83 | 84 | /********************************************************************** 85 | * Document-class: Symbol 86 | * 87 | * Symbol objects represent names and some strings 88 | * inside the Ruby 89 | * interpreter. They are generated using the :name and 90 | * :"string" literals 91 | * syntax, and by the various to_sym methods. The same 92 | * Symbol object will be created for a given name or string 93 | * for the duration of a program's execution, regardless of the context 94 | * or meaning of that name. Thus if Fred is a constant in 95 | * one context, a method in another, and a class in a third, the 96 | * Symbol :Fred will be the same object in 97 | * all three contexts. 98 | * 99 | * module One 100 | * class Fred 101 | * end 102 | * $f1 = :Fred 103 | * end 104 | * module Two 105 | * Fred = 1 106 | * $f2 = :Fred 107 | * end 108 | * def Fred() 109 | * end 110 | * $f3 = :Fred 111 | * $f1.object_id #=> 2514190 112 | * $f2.object_id #=> 2514190 113 | * $f3.object_id #=> 2514190 114 | * 115 | */ 116 | 117 | 118 | /* 15.2.11.3.1 */ 119 | /* 120 | * call-seq: 121 | * sym == obj -> true or false 122 | * 123 | * Equality---If sym and obj are exactly the same 124 | * symbol, returns true. 125 | */ 126 | 127 | static mrb_value 128 | sym_equal(mrb_state *mrb, mrb_value sym1) 129 | { 130 | mrb_value sym2; 131 | 132 | mrb_get_args(mrb, "o", &sym2); 133 | if (mrb_obj_equal(mrb, sym1, sym2)) return mrb_true_value(); 134 | return mrb_false_value(); 135 | } 136 | 137 | /* 15.2.11.3.2 */ 138 | /* 15.2.11.3.3 */ 139 | /* 140 | * call-seq: 141 | * sym.id2name -> string 142 | * sym.to_s -> string 143 | * 144 | * Returns the name or string corresponding to sym. 145 | * 146 | * :fred.id2name #=> "fred" 147 | */ 148 | mrb_value 149 | mrb_sym_to_s(mrb_state *mrb, mrb_value sym) 150 | { 151 | mrb_sym id = SYM2ID(sym); 152 | 153 | #ifdef INCLUDE_REGEXP 154 | //return str_new3(mrb_cString, mrb_id2str(id)); 155 | return str_new3(mrb, mrb_obj_class(mrb, sym), mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id))); 156 | #else 157 | return mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id)); //mrb_str_new2(mrb_id2name(SYM2ID(sym))); 158 | #endif 159 | 160 | } 161 | 162 | /* 15.2.11.3.4 */ 163 | /* 164 | * call-seq: 165 | * sym.to_sym -> sym 166 | * sym.intern -> sym 167 | * 168 | * In general, to_sym returns the Symbol corresponding 169 | * to an object. As sym is already a symbol, self is returned 170 | * in this case. 171 | */ 172 | 173 | static mrb_value 174 | sym_to_sym(mrb_state *mrb, mrb_value sym) 175 | { 176 | return sym; 177 | } 178 | 179 | /* 15.2.11.3.5(x) */ 180 | /* 181 | * call-seq: 182 | * sym.inspect -> string 183 | * 184 | * Returns the representation of sym as a symbol literal. 185 | * 186 | * :fred.inspect #=> ":fred" 187 | */ 188 | 189 | static mrb_value 190 | sym_inspect(mrb_state *mrb, mrb_value sym) 191 | { 192 | #ifdef INCLUDE_ENCODING 193 | #define STR_ENC_GET(mrb, str) mrb_enc_from_index(mrb, ENCODING_GET(mrb, str)) 194 | mrb_value str; 195 | mrb_sym id = SYM2ID(sym); 196 | mrb_encoding *enc; 197 | const char *ptr; 198 | long len; 199 | char *dest; 200 | mrb_encoding *resenc = mrb_default_internal_encoding(mrb); 201 | 202 | if (resenc == NULL) resenc = mrb_default_external_encoding(mrb); 203 | sym = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id));//mrb_id2str(id); 204 | enc = STR_ENC_GET(mrb, sym); 205 | ptr = RSTRING_PTR(sym); 206 | len = RSTRING_LEN(sym); 207 | if ((resenc != enc && !mrb_str_is_ascii_only_p(mrb, sym)) || len != (long)strlen(ptr) || 208 | !mrb_enc_symname_p(ptr, enc) || !sym_printable(mrb, ptr, ptr + len, enc)) { 209 | str = mrb_str_inspect(mrb, sym); 210 | len = RSTRING_LEN(str); 211 | mrb_str_resize(mrb, str, len + 1); 212 | dest = RSTRING_PTR(str); 213 | memmove(dest + 1, dest, len); 214 | dest[0] = ':'; 215 | } 216 | else { 217 | char *dest; 218 | str = mrb_enc_str_new(mrb, 0, len + 1, enc); 219 | dest = RSTRING_PTR(str); 220 | dest[0] = ':'; 221 | memcpy(dest + 1, ptr, len); 222 | } 223 | return str; 224 | #else 225 | mrb_value str; 226 | const char *name; 227 | mrb_sym id = SYM2ID(sym); 228 | 229 | name = mrb_sym2name(mrb, id); //mrb_id2name(id); 230 | str = mrb_str_new(mrb, 0, strlen(name)+1); 231 | RSTRING(str)->buf[0] = ':'; 232 | strcpy(RSTRING(str)->buf+1, name); 233 | if (!mrb_symname_p(name)) { 234 | str = mrb_str_dump(mrb, str); 235 | strncpy(RSTRING(str)->buf, ":\"", 2); 236 | } 237 | return str; 238 | #endif 239 | } 240 | 241 | 242 | void 243 | mrb_init_symbols(mrb_state *mrb) 244 | { 245 | struct RClass *sym; 246 | 247 | sym = mrb->symbol_class = mrb_define_class(mrb, "Symbol", mrb->object_class); 248 | 249 | mrb_define_method(mrb, sym, "===", sym_equal, ARGS_REQ(1)); /* 15.2.11.3.1 */ 250 | mrb_define_method(mrb, sym, "id2name", mrb_sym_to_s, ARGS_NONE()); /* 15.2.11.3.2 */ 251 | mrb_define_method(mrb, sym, "to_s", mrb_sym_to_s, ARGS_NONE()); /* 15.2.11.3.3 */ 252 | mrb_define_method(mrb, sym, "to_sym", sym_to_sym, ARGS_NONE()); /* 15.2.11.3.4 */ 253 | 254 | mrb_define_method(mrb, sym, "inspect", sym_inspect, ARGS_NONE()); /* 15.2.11.3.5(x) */ 255 | } 256 | -------------------------------------------------------------------------------- /src/transcode_data.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | transcode_data.h - 4 | 5 | $Author: duerst $ 6 | created at: Mon 10 Dec 2007 14:01:47 JST 2007 7 | 8 | Copyright (C) 2007 Martin Duerst 9 | 10 | **********************************************************************/ 11 | 12 | //#include "ruby/ruby.h" 13 | 14 | #ifndef RUBY_TRANSCODE_DATA_H 15 | #define RUBY_TRANSCODE_DATA_H 1 16 | 17 | #define WORDINDEX_SHIFT_BITS 2 18 | #define WORDINDEX2INFO(widx) ((widx) << WORDINDEX_SHIFT_BITS) 19 | #define INFO2WORDINDEX(info) ((info) >> WORDINDEX_SHIFT_BITS) 20 | #define BYTE_LOOKUP_BASE(bl) ((bl)[0]) 21 | #define BYTE_LOOKUP_INFO(bl) ((bl)[1]) 22 | 23 | #define PType (unsigned int) 24 | 25 | #define NOMAP (PType 0x01) /* direct map */ 26 | #define ONEbt (0x02) /* one byte payload */ 27 | #define TWObt (0x03) /* two bytes payload */ 28 | #define THREEbt (0x05) /* three bytes payload */ 29 | #define FOURbt (0x06) /* four bytes payload, UTF-8 only, macros start at getBT0 */ 30 | #define INVALID (PType 0x07) /* invalid byte sequence */ 31 | #define UNDEF (PType 0x09) /* legal but undefined */ 32 | #define ZERObt (PType 0x0A) /* zero bytes of payload, i.e. remove */ 33 | #define FUNii (PType 0x0B) /* function from info to info */ 34 | #define FUNsi (PType 0x0D) /* function from start to info */ 35 | #define FUNio (PType 0x0E) /* function from info to output */ 36 | #define FUNso (PType 0x0F) /* function from start to output */ 37 | #define STR1 (PType 0x11) /* string 4 <= len <= 259 bytes: 1byte length + content */ 38 | #define GB4bt (PType 0x12) /* GB18030 four bytes payload */ 39 | #define FUNsio (PType 0x13) /* function from start and info to output */ 40 | 41 | #define STR1_LENGTH(byte_addr) (unsigned int)(*(byte_addr) + 4) 42 | #define STR1_BYTEINDEX(w) ((w) >> 6) 43 | #define makeSTR1(bi) (((bi) << 6) | STR1) 44 | #define makeSTR1LEN(len) ((len)-4) 45 | 46 | #define o1(b1) (PType((((unsigned char)(b1))<<8)|ONEbt)) 47 | #define o2(b1,b2) (PType((((unsigned char)(b1))<<8)|(((unsigned char)(b2))<<16)|TWObt)) 48 | #define o3(b1,b2,b3) (PType(((((unsigned char)(b1))<<8)|(((unsigned char)(b2))<<16)|(((unsigned int)(unsigned char)(b3))<<24)|THREEbt)&0xffffffffU)) 49 | #define o4(b0,b1,b2,b3) (PType(((((unsigned char)(b1))<<8)|(((unsigned char)(b2))<<16)|(((unsigned char)(b3))<<24)|((((unsigned char)(b0))&0x07)<<5)|FOURbt)&0xffffffffU)) 50 | #define g4(b0,b1,b2,b3) (PType(((((unsigned char)(b0))<<8)|(((unsigned char)(b2))<<16)|((((unsigned char)(b1))&0x0f)<<24)|((((unsigned int)(unsigned char)(b3))&0x0f)<<28)|GB4bt)&0xffffffffU)) 51 | #define funsio(diff) (PType((((unsigned int)(diff))<<8)|FUNsio)) 52 | 53 | #define getBT1(a) ((unsigned char)((a)>> 8)) 54 | #define getBT2(a) ((unsigned char)((a)>>16)) 55 | #define getBT3(a) ((unsigned char)((a)>>24)) 56 | #define getBT0(a) (((unsigned char)((a)>> 5)&0x07)|0xF0) /* for UTF-8 only!!! */ 57 | 58 | #define getGB4bt0(a) ((unsigned char)((a)>> 8)) 59 | #define getGB4bt1(a) ((((unsigned char)((a)>>24))&0x0F)|0x30) 60 | #define getGB4bt2(a) ((unsigned char)((a)>>16)) 61 | #define getGB4bt3(a) ((((unsigned char)((a)>>28))&0x0F)|0x30) 62 | 63 | #define o2FUNii(b1,b2) (PType((((unsigned char)(b1))<<8)|(((unsigned char)(b2))<<16)|FUNii)) 64 | 65 | /* do we need these??? maybe not, can be done with simple tables */ 66 | #define ONETRAIL /* legal but undefined if one more trailing UTF-8 */ 67 | #define TWOTRAIL /* legal but undefined if two more trailing UTF-8 */ 68 | #define THREETRAIL /* legal but undefined if three more trailing UTF-8 */ 69 | 70 | typedef enum { 71 | asciicompat_converter, /* ASCII-compatible -> ASCII-compatible */ 72 | asciicompat_decoder, /* ASCII-incompatible -> ASCII-compatible */ 73 | asciicompat_encoder /* ASCII-compatible -> ASCII-incompatible */ 74 | /* ASCII-incompatible -> ASCII-incompatible is intentionally omitted. */ 75 | } mrb_transcoder_asciicompat_type_t; 76 | 77 | typedef struct mrb_transcoder mrb_transcoder; 78 | 79 | /* static structure, one per supported encoding pair */ 80 | struct mrb_transcoder { 81 | const char *src_encoding; 82 | const char *dst_encoding; 83 | unsigned int conv_tree_start; 84 | const unsigned char *byte_array; 85 | unsigned int byte_array_length; 86 | const unsigned int *word_array; 87 | unsigned int word_array_length; 88 | int word_size; 89 | int input_unit_length; 90 | int max_input; 91 | int max_output; 92 | mrb_transcoder_asciicompat_type_t asciicompat_type; 93 | size_t state_size; 94 | int (*state_init_func)(void*); /* ret==0:success ret!=0:failure(errno) */ 95 | int (*state_fini_func)(void*); /* ret==0:success ret!=0:failure(errno) */ 96 | mrb_value (*func_ii)(void*, mrb_value); /* info -> info */ 97 | mrb_value (*func_si)(void*, const unsigned char*, size_t); /* start -> info */ 98 | ssize_t (*func_io)(void*, mrb_value, const unsigned char*, size_t); /* info -> output */ 99 | ssize_t (*func_so)(void*, const unsigned char*, size_t, unsigned char*, size_t); /* start -> output */ 100 | ssize_t (*finish_func)(void*, unsigned char*, size_t); /* -> output */ 101 | ssize_t (*resetsize_func)(void*); /* -> len */ 102 | ssize_t (*resetstate_func)(void*, unsigned char*, size_t); /* -> output */ 103 | ssize_t (*func_sio)(void*, const unsigned char*, size_t, mrb_value, unsigned char*, size_t); /* start -> output */ 104 | }; 105 | 106 | void mrb_declare_transcoder(mrb_state *mrb, const char *enc1, const char *enc2, const char *lib); 107 | void mrb_register_transcoder(mrb_state *mrb, const mrb_transcoder *); 108 | 109 | #endif /* RUBY_TRANSCODE_DATA_H */ 110 | -------------------------------------------------------------------------------- /src/us_ascii.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #ifdef INCLUDE_ENCODING 3 | #include "regenc.h" 4 | 5 | static int 6 | us_ascii_mbc_enc_len(const UChar* p, const UChar* e, OnigEncoding enc) 7 | { 8 | if (*p & 0x80) 9 | return ONIGENC_CONSTRUCT_MBCLEN_INVALID(); 10 | return ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(1); 11 | } 12 | 13 | OnigEncodingDefine(us_ascii, US_ASCII) = { 14 | us_ascii_mbc_enc_len, 15 | "US-ASCII",/* name */ 16 | 1, /* max byte length */ 17 | 1, /* min byte length */ 18 | onigenc_is_mbc_newline_0x0a, 19 | onigenc_single_byte_mbc_to_code, 20 | onigenc_single_byte_code_to_mbclen, 21 | onigenc_single_byte_code_to_mbc, 22 | onigenc_ascii_mbc_case_fold, 23 | onigenc_ascii_apply_all_case_fold, 24 | onigenc_ascii_get_case_fold_codes_by_str, 25 | onigenc_minimum_property_name_to_ctype, 26 | onigenc_ascii_is_code_ctype, 27 | onigenc_not_support_get_ctype_code_range, 28 | onigenc_single_byte_left_adjust_char_head, 29 | onigenc_always_true_is_allowed_reverse_match 30 | }; 31 | ENC_ALIAS("ASCII", "US-ASCII") 32 | ENC_ALIAS("ANSI_X3.4-1968", "US-ASCII") 33 | ENC_ALIAS("646", "US-ASCII") 34 | #endif //INCLUDE_ENCODING 35 | -------------------------------------------------------------------------------- /src/variable.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include "mruby/class.h" 3 | #include "ritehash.h" 4 | #include "variable.h" 5 | #include "mruby/string.h" 6 | #include "mruby/range.h" 7 | #include "error.h" 8 | #include "mruby/array.h" 9 | 10 | #ifdef INCLUDE_REGEXP 11 | #include "re.h" 12 | #include "st.h" 13 | #endif 14 | 15 | KHASH_MAP_INIT_INT(iv, mrb_value); 16 | 17 | #ifndef FALSE 18 | #define FALSE 0 19 | #endif 20 | 21 | #ifndef TRUE 22 | #define TRUE 1 23 | #endif 24 | 25 | static void 26 | mark_tbl(mrb_state *mrb, struct kh_iv *h) 27 | { 28 | khiter_t k; 29 | 30 | if (!h) return; 31 | for (k = kh_begin(h); k != kh_end(h); k++) 32 | if (kh_exist(h, k)) 33 | mrb_gc_mark_value(mrb, kh_value(h, k)); 34 | } 35 | 36 | void 37 | mrb_gc_mark_gv(mrb_state *mrb) 38 | { 39 | mark_tbl(mrb, mrb->globals); 40 | } 41 | 42 | void 43 | mrb_gc_free_gv(mrb_state *mrb) 44 | { 45 | kh_destroy(iv, mrb->globals); 46 | } 47 | 48 | void 49 | mrb_gc_mark_iv(mrb_state *mrb, struct RObject *obj) 50 | { 51 | mark_tbl(mrb, obj->iv); 52 | } 53 | 54 | size_t 55 | mrb_gc_mark_iv_size(mrb_state *mrb, struct RObject *obj) 56 | { 57 | khiter_t k; 58 | struct kh_iv *h = obj->iv; 59 | 60 | if (!h) return 0; 61 | return kh_size(h); 62 | } 63 | 64 | void 65 | mrb_gc_free_iv(mrb_state *mrb, struct RObject *obj) 66 | { 67 | kh_destroy(iv, obj->iv); 68 | } 69 | 70 | mrb_value 71 | mrb_vm_special_get(mrb_state *mrb, mrb_sym i) 72 | { 73 | return mrb_fixnum_value(0); 74 | } 75 | 76 | void 77 | mrb_vm_special_set(mrb_state *mrb, mrb_sym i, mrb_value v) 78 | { 79 | } 80 | 81 | static mrb_value 82 | ivget(mrb_state *mrb, struct kh_iv *h, mrb_sym sym) 83 | { 84 | khiter_t k; 85 | 86 | k = kh_get(iv, h, sym); 87 | if (k != kh_end(h)) 88 | return kh_value(h, k); 89 | return mrb_nil_value(); 90 | } 91 | 92 | mrb_value 93 | mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym) 94 | { 95 | if (!obj->iv) { 96 | return mrb_nil_value(); 97 | } 98 | return ivget(mrb, obj->iv, sym); 99 | } 100 | 101 | mrb_value 102 | mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym) 103 | { 104 | return mrb_obj_iv_get(mrb, mrb_obj_ptr(obj), sym); 105 | } 106 | 107 | static void 108 | ivset(mrb_state *mrb, struct kh_iv *h, mrb_sym sym, mrb_value v) 109 | { 110 | khiter_t k; 111 | int r; 112 | 113 | k = kh_put(iv, h, sym, &r); 114 | kh_value(h, k) = v; 115 | } 116 | 117 | void 118 | mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) 119 | { 120 | khash_t(iv) *h; 121 | 122 | if (!obj->iv) { 123 | h = obj->iv = kh_init(iv, mrb); 124 | } 125 | else { 126 | h = obj->iv; 127 | } 128 | mrb_write_barrier(mrb, (struct RBasic*)obj); 129 | ivset(mrb, h, sym, v); 130 | } 131 | 132 | void 133 | mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v) /* mrb_ivar_set */ 134 | { 135 | mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), sym, v); 136 | } 137 | 138 | mrb_value 139 | mrb_vm_iv_get(mrb_state *mrb, mrb_sym sym) 140 | { 141 | /* get self */ 142 | return mrb_iv_get(mrb, mrb->stack[0], sym); 143 | } 144 | 145 | void 146 | mrb_vm_iv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) 147 | { 148 | /* get self */ 149 | mrb_iv_set(mrb, mrb->stack[0], sym, v); 150 | } 151 | 152 | mrb_value 153 | mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) 154 | { 155 | struct RClass *c = mrb->ci->target_class; 156 | 157 | while (c) { 158 | if (c->iv) { 159 | khash_t(iv) *h = c->iv; 160 | khiter_t k = kh_get(iv, h, sym); 161 | 162 | if (k != kh_end(h)) 163 | return kh_value(h, k); 164 | } 165 | c = c->super; 166 | } 167 | return mrb_nil_value(); 168 | } 169 | 170 | void 171 | mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) 172 | { 173 | struct RClass *c = mrb->ci->target_class; 174 | khash_t(iv) *h; 175 | khiter_t k; 176 | int r; 177 | 178 | while (c) { 179 | if (c->iv) { 180 | h = c->iv; 181 | k = kh_get(iv, h, sym); 182 | if (k != kh_end(h)) { 183 | k = kh_put(iv, h, sym, &r); 184 | kh_value(h, k) = v; 185 | } 186 | } 187 | c = c->super; 188 | } 189 | c = mrb->ci->target_class; 190 | h = c->iv = kh_init(iv, mrb); 191 | k = kh_put(iv, h, sym, &r); 192 | kh_value(h, k) = v; 193 | } 194 | 195 | int 196 | mrb_const_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym) 197 | { 198 | khiter_t k; 199 | struct RClass *m = mrb_class_ptr(mod); 200 | struct kh_iv *h = m->iv; 201 | 202 | if (!h) return 0; 203 | k = kh_get(iv, h, sym); 204 | if (k != kh_end(h)) 205 | return 1; 206 | return 0; 207 | } 208 | 209 | static void 210 | mod_const_check(mrb_state *mrb, mrb_value mod) 211 | { 212 | switch (mod.tt) { 213 | case MRB_TT_CLASS: 214 | case MRB_TT_MODULE: 215 | break; 216 | default: 217 | mrb_raise(mrb, E_TYPE_ERROR, "constant look-up for non class/module"); 218 | break; 219 | } 220 | } 221 | 222 | static mrb_value 223 | const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym) 224 | { 225 | struct RClass *c = base; 226 | khash_t(iv) *h; 227 | khiter_t k; 228 | 229 | if (c->iv) { 230 | h = c->iv; 231 | k = kh_get(iv, h, sym); 232 | if (k != kh_end(h)) { 233 | return kh_value(h, k); 234 | } 235 | } 236 | for (;;) { 237 | c = mrb_class_outer_module(mrb, c); 238 | if (!c) break; 239 | if (c->iv) { 240 | h = c->iv; 241 | k = kh_get(iv, h, sym); 242 | if (k != kh_end(h)) { 243 | return kh_value(h, k); 244 | } 245 | } 246 | } 247 | c = base->super; 248 | while (c) { 249 | if (c->iv) { 250 | h = c->iv; 251 | k = kh_get(iv, h, sym); 252 | if (k != kh_end(h)) { 253 | return kh_value(h, k); 254 | } 255 | } 256 | c = c->super; 257 | } 258 | mrb_raise(mrb, E_NAME_ERROR, "uninitialized constant %s", 259 | mrb_sym2name(mrb, sym)); 260 | /* not reached */ 261 | return mrb_nil_value(); 262 | } 263 | 264 | mrb_value 265 | mrb_const_get(mrb_state *mrb, mrb_value mod, mrb_sym sym) 266 | { 267 | mod_const_check(mrb, mod); 268 | return const_get(mrb, mrb_class_ptr(mod), sym); 269 | } 270 | 271 | mrb_value 272 | mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) 273 | { 274 | return const_get(mrb, mrb->ci->target_class, sym); 275 | } 276 | 277 | void 278 | mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v) 279 | { 280 | mod_const_check(mrb, mod); 281 | mrb_iv_set(mrb, mod, sym, v); 282 | } 283 | 284 | void 285 | mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v) 286 | { 287 | mrb_obj_iv_set(mrb, (struct RObject*)mrb->ci->target_class, sym, v); 288 | } 289 | 290 | void 291 | mrb_define_const(mrb_state *mrb, struct RClass *mod, const char *name, mrb_value v) 292 | { 293 | mrb_obj_iv_set(mrb, (struct RObject*)mod, mrb_intern(mrb, name), v); 294 | } 295 | 296 | void 297 | mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val) 298 | { 299 | mrb_define_const(mrb, mrb->object_class, name, val); 300 | } 301 | 302 | mrb_value 303 | mrb_gv_get(mrb_state *mrb, mrb_sym sym) 304 | { 305 | if (!mrb->globals) { 306 | return mrb_nil_value(); 307 | } 308 | return ivget(mrb, mrb->globals, sym); 309 | } 310 | 311 | void 312 | mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) 313 | { 314 | khash_t(iv) *h; 315 | 316 | if (!mrb->globals) { 317 | h = mrb->globals = kh_init(iv, mrb); 318 | } 319 | else { 320 | h = mrb->globals; 321 | } 322 | ivset(mrb, h, sym, v); 323 | } 324 | 325 | /* 15.3.1.2.4 */ 326 | /* 15.3.1.3.14 */ 327 | /* 328 | * call-seq: 329 | * global_variables -> array 330 | * 331 | * Returns an array of the names of global variables. 332 | * 333 | * global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr] 334 | */ 335 | mrb_value 336 | mrb_f_global_variables(mrb_state *mrb, mrb_value self) 337 | { 338 | char buf[3]; 339 | int i; 340 | struct kh_iv *h = mrb->globals; 341 | mrb_value ary = mrb_ary_new(mrb); 342 | 343 | for (i=0;i< kh_end(h);i++) { 344 | if (kh_exist(h, i)) { 345 | mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(h,i))); 346 | } 347 | } 348 | buf[0] = '$'; 349 | buf[2] = 0; 350 | for (i = 1; i <= 9; ++i) { 351 | buf[1] = (char)(i + '0'); 352 | mrb_ary_push(mrb, ary, mrb_symbol_value(mrb_intern(mrb, buf))); 353 | } 354 | return ary; 355 | } 356 | 357 | int 358 | mrb_st_lookup(struct kh_iv *table, mrb_sym id, khiter_t *value) 359 | { 360 | khash_t(iv) *h; 361 | khiter_t k; 362 | 363 | if (table) { 364 | h = (khash_t(iv) *)table; 365 | k = kh_get(iv, h, id); 366 | if (k != kh_end(h)) { 367 | if (value != 0) *value = k;//kh_value(h, k); 368 | return 1;/* TRUE */ 369 | } 370 | return 0;/* FALSE */ 371 | } 372 | else { 373 | return 0;/* FALSE */ 374 | } 375 | } 376 | 377 | int 378 | kiv_lookup(khash_t(iv)* table, mrb_sym key, mrb_value *value) 379 | { 380 | khash_t(iv) *h=table; 381 | khiter_t k; 382 | 383 | // you must check(iv==0), before you call this function. 384 | //if (!obj->iv) { 385 | // return 0; 386 | //} 387 | k = kh_get(iv, h, key); 388 | if (k != kh_end(h)) { 389 | *value = kh_value(h, k); 390 | return 1; 391 | } 392 | return 0; 393 | } 394 | 395 | static int 396 | mrb_const_defined_0(mrb_state *mrb, struct RClass *klass, mrb_sym id, int exclude, int recurse) 397 | { 398 | mrb_value value; 399 | struct RClass * tmp; 400 | int mod_retry = 0; 401 | 402 | tmp = klass; 403 | retry: 404 | while (tmp) { 405 | if (tmp->iv && kiv_lookup(tmp->iv, id, &value)) { 406 | return (int)1/*Qtrue*/; 407 | } 408 | if (!recurse && (klass != mrb->object_class)) break; 409 | tmp = tmp->super; 410 | } 411 | if (!exclude && !mod_retry && (klass->tt == MRB_TT_MODULE)) { 412 | mod_retry = 1; 413 | tmp = mrb->object_class; 414 | goto retry; 415 | } 416 | return (int)0/*Qfalse*/; 417 | } 418 | 419 | int 420 | mrb_const_defined_at(mrb_state *mrb, struct RClass *klass, mrb_sym id) 421 | { 422 | return mrb_const_defined_0(mrb, klass, id, TRUE, FALSE); 423 | } 424 | 425 | struct RClass * 426 | mrb_class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id) 427 | { 428 | mrb_value c = const_get(mrb, klass, id); 429 | return mrb_class_ptr(c); 430 | } 431 | 432 | struct RClass * 433 | mrb_class_get(mrb_state *mrb, char *name) 434 | { 435 | return mrb_class_from_sym(mrb, mrb->object_class, mrb_intern(mrb, name)); 436 | } 437 | 438 | mrb_value 439 | mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id) 440 | { 441 | //return ivar_get(obj, id, FALSE); 442 | return mrb_iv_get(mrb, obj, id); 443 | } 444 | 445 | struct RClass * 446 | mrb_class_obj_get(mrb_state *mrb, char *name) 447 | { 448 | mrb_value mod = mrb_obj_value(mrb->object_class); 449 | mrb_sym sym = mrb_intern(mrb, name); 450 | 451 | return mrb_class_ptr(mrb_const_get(mrb, mod, sym)); 452 | } 453 | 454 | -------------------------------------------------------------------------------- /src/variable.h: -------------------------------------------------------------------------------- 1 | #ifndef MRUBY_VARIABLE_H 2 | #define MRUBY_VARIABLE_H 3 | 4 | typedef struct global_variable { 5 | int counter; 6 | mrb_value *data; 7 | mrb_value (*getter)(); 8 | void (*setter)(); 9 | //void (*marker)(); 10 | //int block_trace; 11 | //struct trace_var *trace; 12 | } global_variable; 13 | struct global_entry { 14 | global_variable *var; 15 | mrb_sym id; 16 | }; 17 | 18 | mrb_value mrb_vm_special_get(mrb_state*, mrb_sym); 19 | void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value); 20 | mrb_value mrb_vm_iv_get(mrb_state*, mrb_sym); 21 | void mrb_vm_iv_set(mrb_state*, mrb_sym, mrb_value); 22 | mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym); 23 | void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value); 24 | mrb_value mrb_vm_const_get(mrb_state*, mrb_sym); 25 | void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value); 26 | mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym); 27 | void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value); 28 | int mrb_const_defined(mrb_state*, mrb_value, mrb_sym); 29 | 30 | mrb_value mrb_obj_iv_get(mrb_state*, struct RObject*, mrb_sym); 31 | void mrb_obj_iv_set(mrb_state*, struct RObject*, mrb_sym, mrb_value); 32 | const char * mrb_class2name(mrb_state *mrb, struct RClass* klass); 33 | void mrb_define_variable(mrb_state *mrb, const char *name, mrb_value *var); 34 | mrb_value mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym); 35 | void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v); /* mrb_iv_set */ 36 | void mrb_copy_generic_ivar(mrb_value clone, mrb_value obj); 37 | int mrb_const_defined_at(mrb_state *mrb, struct RClass *klass, mrb_sym id); 38 | mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self); 39 | mrb_value mrb_gv_get(mrb_state *mrb, mrb_sym sym); 40 | void mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value val); 41 | 42 | #endif /* MRUBY_VARIABLE_H */ 43 | -------------------------------------------------------------------------------- /src/version.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | version.c - 4 | 5 | $Author: knu $ 6 | $Date: 2008-05-31 22:37:06 +0900 (Sat, 31 May 2008) $ 7 | created at: Thu Sep 30 20:08:01 JST 1993 8 | 9 | Copyright (C) 1993-2003 Yukihiro Matsumoto 10 | 11 | **********************************************************************/ 12 | 13 | #include "mruby.h" 14 | #include "version.h" 15 | #include 16 | #include "mruby/string.h" 17 | #include "variable.h" 18 | 19 | #define PRINT(type) puts(ruby_##type) 20 | //#define MKSTR(type) mrb_obj_freeze(mrb_str_new(ruby_##type, sizeof(ruby_##type)-1)) 21 | #define MKSTR(type) mrb_str_new(mrb, ruby_##type, sizeof(ruby_##type)-1) 22 | 23 | const char ruby_version[] = RUBY_VERSION; 24 | const char ruby_release_date[] = RUBY_RELEASE_DATE; 25 | const char ruby_platform[] = RUBY_PLATFORM; 26 | const int ruby_patchlevel = RUBY_PATCHLEVEL; 27 | const char ruby_engine[] = RUBY_ENGINE; 28 | 29 | void 30 | Init_version(mrb_state *mrb) 31 | { 32 | char description[128]; 33 | char copyright[128]; 34 | mrb_value v = MKSTR(version); 35 | mrb_value d = MKSTR(release_date); 36 | mrb_value p = MKSTR(platform); 37 | mrb_value e = MKSTR(engine); 38 | mrb_value tmp; 39 | 40 | mrb_define_global_const(mrb, "RUBY_VERSION", v); 41 | mrb_define_global_const(mrb, "RUBY_RELEASE_DATE", d); 42 | mrb_define_global_const(mrb, "RUBY_PLATFORM", p); 43 | mrb_define_global_const(mrb, "RUBY_PATCHLEVEL", mrb_fixnum_value(RUBY_PATCHLEVEL)); 44 | mrb_define_global_const(mrb, "RUBY_ENGINE", e); 45 | 46 | snprintf(description, sizeof(description), "ruby %s (%s %s %d) [%s]", 47 | RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_RELEASE_STR, 48 | RUBY_RELEASE_NUM, RUBY_PLATFORM); 49 | //tmp = mrb_obj_freeze(mrb_str_new2(description)); 50 | tmp = mrb_str_new2(mrb, description); 51 | mrb_define_global_const(mrb, "RUBY_DESCRIPTION", tmp); 52 | 53 | snprintf(copyright, sizeof(copyright), "ruby - Copyright (C) %d-%d %s", 54 | RUBY_BIRTH_YEAR, RUBY_RELEASE_YEAR, RUBY_AUTHOR); 55 | //tmp = mrb_obj_freeze(mrb_str_new2(copyright)); 56 | tmp = mrb_str_new2(mrb, copyright); 57 | mrb_define_global_const(mrb, "RUBY_COPYRIGHT", tmp); 58 | 59 | /* obsolete constants */ 60 | mrb_define_global_const(mrb, "VERSION", v); 61 | mrb_define_global_const(mrb, "RELEASE_DATE", d); 62 | mrb_define_global_const(mrb, "PLATFORM", p); 63 | } 64 | 65 | void 66 | ruby_show_version(mrb_state *mrb) 67 | { 68 | mrb_value v = mrb_const_get(mrb, mrb_obj_value(mrb->object_class), mrb_intern(mrb, "RUBY_DESCRIPTION")); 69 | 70 | if (mrb_type(v) != MRB_TT_STRING) 71 | return; 72 | 73 | puts(RSTRING_PTR(v)); 74 | fflush(stdout); 75 | } 76 | 77 | void 78 | ruby_show_copyright(mrb_state *mrb) 79 | { 80 | mrb_value v = mrb_const_get(mrb, mrb_obj_value(mrb->object_class), mrb_intern(mrb, "RUBY_COPYRIGHT")); 81 | 82 | if (mrb_type(v) != MRB_TT_STRING) 83 | return; 84 | 85 | puts(RSTRING_PTR(v)); 86 | exit(0); 87 | } 88 | -------------------------------------------------------------------------------- /src/version.h: -------------------------------------------------------------------------------- 1 | #define RUBY_VERSION "1.8.7" 2 | #define RUBY_RELEASE_DATE "2010-08-16" 3 | #define RUBY_VERSION_CODE 187 4 | #define RUBY_RELEASE_CODE 20100816 5 | #define RUBY_PATCHLEVEL 302 6 | 7 | #define RUBY_VERSION_MAJOR 1 8 | #define RUBY_VERSION_MINOR 8 9 | #define RUBY_VERSION_TEENY 7 10 | #define RUBY_RELEASE_YEAR 2010 11 | #define RUBY_RELEASE_MONTH 8 12 | #define RUBY_RELEASE_DAY 16 13 | 14 | #ifdef RUBY_EXTERN 15 | RUBY_EXTERN const char ruby_version[]; 16 | RUBY_EXTERN const char ruby_release_date[]; 17 | RUBY_EXTERN const char ruby_platform[]; 18 | RUBY_EXTERN const int ruby_patchlevel; 19 | RUBY_EXTERN const char *ruby_description; 20 | RUBY_EXTERN const char *ruby_copyright; 21 | #endif 22 | 23 | #define RUBY_AUTHOR "Yukihiro Matsumoto" 24 | #define RUBY_BIRTH_YEAR 1993 25 | #define RUBY_BIRTH_MONTH 2 26 | #define RUBY_BIRTH_DAY 24 27 | 28 | #define RUBY_RELEASE_STR "patchlevel" 29 | #define RUBY_RELEASE_NUM RUBY_PATCHLEVEL 30 | 31 | #define RUBY_PLATFORM "i386-mingw32" 32 | #define RUBY_ENGINE "ruby" 33 | -------------------------------------------------------------------------------- /tools/mrbc/Makefile: -------------------------------------------------------------------------------- 1 | # makefile discription. 2 | # basic build file for Rite-Compiler 3 | # 11.Apr.2011 coded by Kenji Yoshimoto. 4 | # 31.Aug.2011 coded by Hiroshi Mimaki. 5 | 6 | # project-specific macros 7 | # extension of the executable-file is modifiable(.exe .out ...) 8 | BASEDIR := ../../src 9 | TARGET := ../../bin/mrbc 10 | ifeq ($(OS),Windows_NT) 11 | EXE := $(TARGET).exe 12 | else 13 | EXE := $(TARGET) 14 | endif 15 | YSRC := $(BASEDIR)/parse.y 16 | YC := $(BASEDIR)/y.tab.c 17 | EXCEPT1 := $(YC) $(BASEDIR)/minimain.c $(BASEDIR)/load.c $(BASEDIR)/init_ext.c 18 | OBJY := $(patsubst %.c,%.o,$(YC)) 19 | OBJ0 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/../tools/mrbc/*.c)) 20 | OBJ1 := $(patsubst %.c,%.o,$(filter-out $(EXCEPT1),$(wildcard $(BASEDIR)/*.c))) 21 | #OBJ2 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/regex/*.c)) 22 | #OBJ3 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/enc/*.c)) 23 | OBJS := $(OBJ0) $(OBJ1) $(OBJ2) $(OBJ3) 24 | 25 | # libraries, includes 26 | LIBS = -lm 27 | INCLUDES = -I$(BASEDIR) -I$(BASEDIR)/../include 28 | 29 | # compiler, linker (gcc) 30 | CC = gcc 31 | LL = gcc 32 | YACC = bison 33 | DEBUG_MODE = 1 34 | ifeq ($(DEBUG_MODE),1) 35 | CFLAGS = -g 36 | else 37 | CFLAGS = -O3 38 | endif 39 | ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS) 40 | MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL) 41 | 42 | ############################## 43 | # generic build targets, rules 44 | 45 | .PHONY : all 46 | all : $(EXE) 47 | @echo "make: built targets of `pwd`" 48 | 49 | # executable constructed using linker from object files 50 | $(EXE) : $(OBJS) $(OBJY) 51 | $(LL) -o $@ $(OBJS) $(OBJY) $(LIBS) 52 | 53 | -include $(OBJS:.o=.d) $(OBJY:.o=.d) 54 | 55 | # objects compiled from source 56 | $(OBJS) : %.o : %.c 57 | $(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@ 58 | 59 | # parser complie 60 | $(OBJY) : $(YC) 61 | $(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $(YC) -o $(OBJY) 62 | 63 | # yacc complie 64 | $(YC) : $(YSRC) 65 | $(YACC) -o $(YC) $(YSRC) 66 | 67 | # clean up 68 | .PHONY : clean 69 | clean : 70 | -rm -f $(EXE) $(OBJS) $(OBJY) $(YC) 71 | -rm -f $(OBJS:.o=.d) $(OBJY:.o=.d) 72 | @echo "make: removing targets, objects and depend files of `pwd`" 73 | 74 | -------------------------------------------------------------------------------- /tools/mrbc/mrbc.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include "mruby/proc.h" 3 | #include "compile.h" 4 | #include "dump.h" 5 | #include "cdump.h" 6 | #include "stdio.h" 7 | #include "memory.h" 8 | #include "stdlib.h" 9 | 10 | #define RITEBIN_EXT ".mrb" 11 | #define C_EXT ".c" 12 | void ruby_show_version(mrb_state *); 13 | void ruby_show_copyright(mrb_state *); 14 | void parser_dump(mrb_state*, struct mrb_ast_node*, int); 15 | void codedump_all(mrb_state*, int); 16 | 17 | struct _args { 18 | FILE *rfp; 19 | FILE *wfp; 20 | char *initname; 21 | char *ext; 22 | int check_syntax : 1; 23 | int dump_type : 2; 24 | int verbose : 1; 25 | }; 26 | 27 | static void 28 | usage(const char *name) 29 | { 30 | static const char *const usage_msg[] = { 31 | "switches:", 32 | "-c check syntax only", 33 | "-o place the output into ", 34 | "-v print version number, then trun on verbose mode", 35 | "-B binary output in C language format", 36 | "-C function output in C language format", 37 | "--verbose run at verbose mode", 38 | "--version print the version", 39 | "--copyright print the copyright", 40 | NULL 41 | }; 42 | const char *const *p = usage_msg; 43 | 44 | printf("Usage: %s [switches] programfile\n", name); 45 | while(*p) 46 | printf(" %s\n", *p++); 47 | } 48 | 49 | static char * 50 | get_outfilename(char *infile, char *ext) 51 | { 52 | char *outfile; 53 | char *p; 54 | 55 | outfile = (char*)malloc(strlen(infile) + strlen(ext) + 1); 56 | strcpy(outfile, infile); 57 | if (*ext) { 58 | if ((p = strrchr(outfile, '.')) == NULL) 59 | p = &outfile[strlen(outfile)]; 60 | strcpy(p, ext); 61 | } 62 | 63 | return outfile; 64 | } 65 | 66 | static int 67 | parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) 68 | { 69 | char *infile = NULL; 70 | char *outfile = NULL; 71 | char **origargv = argv; 72 | 73 | memset(args, 0, sizeof(*args)); 74 | args->ext = RITEBIN_EXT; 75 | 76 | for (argc--,argv++; argc > 0; argc--,argv++) { 77 | if (**argv == '-') { 78 | if (strlen(*argv) <= 1) 79 | return -1; 80 | 81 | switch ((*argv)[1]) { 82 | case 'o': 83 | outfile = get_outfilename((*argv) + 2, ""); 84 | break; 85 | case 'B': 86 | case 'C': 87 | args->ext = C_EXT; 88 | args->initname = (*argv) + 2; 89 | if (*args->initname == '\0') { 90 | printf("%s: Function name is not specified.\n", *origargv); 91 | return -2; 92 | } 93 | args->dump_type = ((*argv)[1] == 'B') ? DUMP_TYPE_BIN : DUMP_TYPE_CODE; 94 | break; 95 | case 'c': 96 | args->check_syntax = 1; 97 | break; 98 | case 'v': 99 | ruby_show_version(mrb); 100 | args->verbose = 1; 101 | break; 102 | case '-': 103 | if (strcmp((*argv) + 2, "version") == 0) { 104 | ruby_show_version(mrb); 105 | } 106 | else if (strcmp((*argv) + 2, "verbose") == 0) { 107 | args->verbose = 1; 108 | break; 109 | } 110 | else if (strcmp((*argv) + 2, "copyright") == 0) { 111 | ruby_show_copyright(mrb); 112 | } 113 | else return -3; 114 | return 0; 115 | } 116 | } 117 | else if (args->rfp == NULL) { 118 | infile = *argv; 119 | if ((args->rfp = fopen(infile, "r")) == NULL) { 120 | printf("%s: Cannot open program file. (%s)\n", *origargv, infile); 121 | return 0; 122 | } 123 | } 124 | } 125 | 126 | if (infile == NULL) 127 | return -4; 128 | if (args->check_syntax) 129 | return 0; 130 | 131 | if (outfile == NULL) 132 | outfile = get_outfilename(infile, args->ext); 133 | 134 | if ((args->wfp = fopen(outfile, "wb")) == NULL) { 135 | printf("%s: Cannot open output file. (%s)\n", *origargv, outfile); 136 | return 0; 137 | } 138 | 139 | return 0; 140 | } 141 | 142 | static void 143 | cleanup(struct _args *args) 144 | { 145 | if (args->rfp) 146 | fclose(args->rfp); 147 | if (args->wfp) 148 | fclose(args->wfp); 149 | } 150 | 151 | int 152 | main(int argc, char **argv) 153 | { 154 | mrb_state *mrb = mrb_open(); 155 | int n = -1; 156 | struct _args args; 157 | struct mrb_parser_state *p; 158 | 159 | n = parse_args(mrb, argc, argv, &args); 160 | 161 | if (n < 0 || args.rfp == NULL) { 162 | cleanup(&args); 163 | usage(argv[0]); 164 | return n; 165 | } 166 | 167 | p = mrb_parse_file(mrb, args.rfp); 168 | if (!p || !p->tree || p->nerr) { 169 | cleanup(&args); 170 | return -1; 171 | } 172 | 173 | if (args.verbose) 174 | parser_dump(mrb, p->tree, 0); 175 | 176 | n = mrb_generate_code(mrb, p->tree); 177 | mrb_pool_close(p->pool); 178 | 179 | if (args.verbose) 180 | codedump_all(mrb, n); 181 | 182 | if (n < 0 || args.check_syntax) { 183 | cleanup(&args); 184 | return n; 185 | } 186 | if (args.initname) { 187 | if (args.dump_type == DUMP_TYPE_BIN) 188 | n = mrb_bdump_irep(mrb, n, args.wfp, args.initname); 189 | else 190 | n = mrb_cdump_irep(mrb, n, args.wfp, args.initname); 191 | } 192 | else { 193 | n = mrb_dump_irep(mrb, n, args.wfp); 194 | } 195 | 196 | cleanup(&args); 197 | 198 | return n; 199 | } 200 | 201 | void 202 | mrb_init_ext(mrb_state *mrb) 203 | { 204 | } 205 | 206 | void 207 | mrb_init_mrblib(mrb_state *mrb) 208 | { 209 | } 210 | 211 | -------------------------------------------------------------------------------- /tools/mruby/Makefile: -------------------------------------------------------------------------------- 1 | # makefile discription. 2 | # basic build file for Rite-Interpreter 3 | # 11.Apr.2011 coded by Kenji Yoshimoto. 4 | # 31.Aug.2011 coded by Hiroshi Mimaki. 5 | 6 | # project-specific macros 7 | # extension of the executable-file is modifiable(.exe .out ...) 8 | BASEDIR = ../../src 9 | TARGET := ../../bin/mruby 10 | ifeq ($(OS),Windows_NT) 11 | EXE := $(TARGET).exe 12 | else 13 | EXE := $(TARGET) 14 | endif 15 | YSRC := $(BASEDIR)/parse.y 16 | YC := $(BASEDIR)/y.tab.c 17 | EXCEPT1 := $(YC) $(BASEDIR)/minimain.c $(BASEDIR)/dump.c $(BASEDIR)/cdump.c 18 | OBJY := $(patsubst %.c,%.o,$(YC)) 19 | OBJ0 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/../tools/mruby/*.c)) 20 | OBJ1 := $(patsubst %.c,%.o,$(filter-out $(EXCEPT1),$(wildcard $(BASEDIR)/*.c))) 21 | #OBJ2 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/regex/*.c)) 22 | #OBJ3 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/enc/*.c)) 23 | OBJS := $(OBJ0) $(OBJ1) $(OBJ2) $(OBJ3) 24 | # mruby libraries 25 | EXTC := $(BASEDIR)/../mrblib/mrblib.c 26 | EXTRB := $(wildcard $(BASEDIR)/../mrblib/*.rb) 27 | EXTM := $(patsubst %.c,%.o,$(EXTC)) 28 | # ext libraries 29 | #EXT1 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/../ext/socket/*.c)) 30 | EXTS := $(EXT1) 31 | 32 | # libraries, includes 33 | LIBS = -lm 34 | INCLUDES = -I$(BASEDIR) -I$(BASEDIR)/../include 35 | #INCLUDES = -I$(RITEVM_ROOT) 36 | 37 | # compiler, linker (gcc) 38 | CC = gcc 39 | LL = gcc 40 | YACC = bison 41 | DEBUG_MODE = 1 42 | ifeq ($(DEBUG_MODE),1) 43 | CFLAGS = -g 44 | else 45 | CFLAGS = -O3 46 | endif 47 | ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS) 48 | MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL) 49 | 50 | ############################## 51 | # generic build targets, rules 52 | 53 | .PHONY : all 54 | all : $(EXTM) $(EXE) 55 | @echo "make: built targets of `pwd`" 56 | 57 | # executable constructed using linker from object files 58 | $(EXE) : $(OBJS) $(OBJY) $(EXTM) $(EXTS) 59 | $(LL) -o $@ $(OBJS) $(OBJY) $(EXTM) $(EXTS) $(LIBS) 60 | 61 | -include $(OBJS:.o=.d) $(OBJY:.o=.d) 62 | 63 | # objects compiled from source 64 | $(OBJS) : %.o : %.c 65 | $(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@ 66 | 67 | # mruby library compile 68 | $(EXTM) : $(EXTRB) $(OBJS) $(OBJY) 69 | $(MAKE) -C ../../mrblib $(MAKE_FLAGS) 70 | 71 | # extend libraries complile 72 | $(EXTS) : %.o : %.c 73 | $(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@ 74 | 75 | # parser complie 76 | $(OBJY) : $(YC) 77 | $(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $(YC) -o $(OBJY) 78 | 79 | # yacc complie 80 | $(YC) : $(YSRC) 81 | $(YACC) -o $(YC) $(YSRC) 82 | 83 | # clean up 84 | .PHONY : clean #cleandep 85 | clean : 86 | $(MAKE) clean -C ../../mrblib $(MAKE_FLAGS) 87 | -rm -f $(EXE) $(OBJS) $(OBJY) $(YC) $(EXTS) 88 | -rm -f $(OBJS:.o=.d) $(OBJY:.o=.d) $(EXTS:.o=.d) 89 | @echo "make: removing targets, objects and depend files of `pwd`" 90 | -------------------------------------------------------------------------------- /tools/mruby/mruby.c: -------------------------------------------------------------------------------- 1 | #include "mruby.h" 2 | #include "mruby/proc.h" 3 | #include "compile.h" 4 | #include "dump.h" 5 | #include "stdio.h" 6 | #include "string.h" 7 | 8 | void ruby_show_version(mrb_state *); 9 | void ruby_show_copyright(mrb_state *); 10 | void parser_dump(mrb_state*, struct mrb_ast_node*, int); 11 | void codedump_all(mrb_state*, int); 12 | 13 | struct _args { 14 | FILE *rfp; 15 | int mrbfile : 1; 16 | int check_syntax : 1; 17 | int verbose : 1; 18 | }; 19 | 20 | static void 21 | usage(const char *name) 22 | { 23 | static const char *const usage_msg[] = { 24 | "switches:", 25 | "-b load and execute RiteBinary(mrb) file", 26 | "-c check syntax only", 27 | "-v print version number, then trun on verbose mode", 28 | "--verbose run at verbose mode", 29 | "--version print the version", 30 | "--copyright print the copyright", 31 | NULL 32 | }; 33 | const char *const *p = usage_msg; 34 | 35 | printf("Usage: %s [switches] programfile\n", name); 36 | while(*p) 37 | printf(" %s\n", *p++); 38 | } 39 | 40 | static int 41 | parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) 42 | { 43 | char **origargv = argv; 44 | 45 | memset(args, 0, sizeof(*args)); 46 | 47 | for (argc--,argv++; argc > 0; argc--,argv++) { 48 | if (**argv == '-') { 49 | if (strlen(*argv) <= 1) 50 | return -1; 51 | 52 | switch ((*argv)[1]) { 53 | case 'b': 54 | args->mrbfile = 1; 55 | break; 56 | case 'c': 57 | args->check_syntax = 1; 58 | break; 59 | case 'v': 60 | ruby_show_version(mrb); 61 | args->verbose = 1; 62 | break; 63 | case '-': 64 | if (strcmp((*argv) + 2, "version") == 0) { 65 | ruby_show_version(mrb); 66 | } 67 | else if (strcmp((*argv) + 2, "verbose") == 0) { 68 | args->verbose = 1; 69 | break; 70 | } 71 | else if (strcmp((*argv) + 2, "copyright") == 0) { 72 | ruby_show_copyright(mrb); 73 | } 74 | else return -3; 75 | return 0; 76 | } 77 | } 78 | else if (args->rfp == NULL) { 79 | if ((args->rfp = fopen(*argv, args->mrbfile ? "rb" : "r")) == NULL) { 80 | printf("%s: Cannot open program file. (%s)\n", *origargv, *argv); 81 | return 0; 82 | } 83 | } 84 | } 85 | 86 | return 0; 87 | } 88 | 89 | static void 90 | cleanup(struct _args *args) 91 | { 92 | if (args->rfp) 93 | fclose(args->rfp); 94 | } 95 | 96 | int 97 | main(int argc, char **argv) 98 | { 99 | mrb_state *mrb = mrb_open(); 100 | int n = -1; 101 | struct _args args; 102 | struct mrb_parser_state *p; 103 | 104 | n = parse_args(mrb, argc, argv, &args); 105 | if (n < 0 || args.rfp == NULL) { 106 | cleanup(&args); 107 | usage(argv[0]); 108 | return n; 109 | } 110 | 111 | if (args.mrbfile) { 112 | n = mrb_load_irep(mrb, args.rfp); 113 | } 114 | else { 115 | p = mrb_parse_file(mrb, args.rfp); 116 | if (!p || !p->tree || p->nerr) { 117 | cleanup(&args); 118 | return -1; 119 | } 120 | 121 | if (args.verbose) 122 | parser_dump(mrb, p->tree, 0); 123 | 124 | n = mrb_generate_code(mrb, p->tree); 125 | mrb_pool_close(p->pool); 126 | } 127 | 128 | if (n >= 0) { 129 | if (args.verbose) 130 | codedump_all(mrb, n); 131 | 132 | if (!args.check_syntax) { 133 | mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_nil_value()); 134 | if (mrb->exc) { 135 | mrb_funcall(mrb, mrb_nil_value(), "p", 1, mrb_obj_value(mrb->exc)); 136 | } 137 | } 138 | } 139 | 140 | cleanup(&args); 141 | 142 | return n; 143 | } 144 | --------------------------------------------------------------------------------