rucc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +55 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +46 -0
  7. data/LICENCE +21 -0
  8. data/README.md +82 -0
  9. data/Rakefile +2 -0
  10. data/Vagrantfile +10 -0
  11. data/bin/console +10 -0
  12. data/bin/rspec +2 -0
  13. data/bin/setup +8 -0
  14. data/exe/rucc +7 -0
  15. data/include/8cc.h +48 -0
  16. data/include/float.h +44 -0
  17. data/include/iso646.h +20 -0
  18. data/include/rucc.h +2 -0
  19. data/include/stdalign.h +11 -0
  20. data/include/stdarg.h +52 -0
  21. data/include/stdbool.h +11 -0
  22. data/include/stddef.h +15 -0
  23. data/include/stdnoreturn.h +8 -0
  24. data/lib/rucc.rb +8 -0
  25. data/lib/rucc/case.rb +22 -0
  26. data/lib/rucc/decl.rb +9 -0
  27. data/lib/rucc/enc.rb +9 -0
  28. data/lib/rucc/engine.rb +138 -0
  29. data/lib/rucc/file_io.rb +108 -0
  30. data/lib/rucc/file_io_list.rb +56 -0
  31. data/lib/rucc/gen.rb +1602 -0
  32. data/lib/rucc/int_evaluator.rb +114 -0
  33. data/lib/rucc/k.rb +73 -0
  34. data/lib/rucc/keyword.rb +17 -0
  35. data/lib/rucc/kind.rb +43 -0
  36. data/lib/rucc/label_gen.rb +13 -0
  37. data/lib/rucc/lexer.rb +40 -0
  38. data/lib/rucc/lexer/impl.rb +683 -0
  39. data/lib/rucc/lexer/preprocessor.rb +888 -0
  40. data/lib/rucc/lexer/preprocessor/cond_incl.rb +27 -0
  41. data/lib/rucc/lexer/preprocessor/constructor.rb +54 -0
  42. data/lib/rucc/lexer/preprocessor/pragma.rb +31 -0
  43. data/lib/rucc/lexer/preprocessor/special_macro.rb +110 -0
  44. data/lib/rucc/libc.rb +47 -0
  45. data/lib/rucc/m.rb +7 -0
  46. data/lib/rucc/macro.rb +24 -0
  47. data/lib/rucc/node.rb +530 -0
  48. data/lib/rucc/node/conv.rb +33 -0
  49. data/lib/rucc/op.rb +61 -0
  50. data/lib/rucc/operator.rb +13 -0
  51. data/lib/rucc/option.rb +30 -0
  52. data/lib/rucc/parser.rb +961 -0
  53. data/lib/rucc/parser/break.rb +18 -0
  54. data/lib/rucc/parser/builtin.rb +25 -0
  55. data/lib/rucc/parser/continue.rb +18 -0
  56. data/lib/rucc/parser/do.rb +33 -0
  57. data/lib/rucc/parser/ensure.rb +39 -0
  58. data/lib/rucc/parser/enum.rb +64 -0
  59. data/lib/rucc/parser/expr.rb +493 -0
  60. data/lib/rucc/parser/for.rb +71 -0
  61. data/lib/rucc/parser/func.rb +274 -0
  62. data/lib/rucc/parser/func_call.rb +54 -0
  63. data/lib/rucc/parser/goto.rb +29 -0
  64. data/lib/rucc/parser/if.rb +23 -0
  65. data/lib/rucc/parser/initializer.rb +237 -0
  66. data/lib/rucc/parser/label.rb +31 -0
  67. data/lib/rucc/parser/return.rb +16 -0
  68. data/lib/rucc/parser/struct_and_union.rb +280 -0
  69. data/lib/rucc/parser/switch.rb +117 -0
  70. data/lib/rucc/parser/while.rb +29 -0
  71. data/lib/rucc/pos.rb +11 -0
  72. data/lib/rucc/rmap.rb +22 -0
  73. data/lib/rucc/s.rb +9 -0
  74. data/lib/rucc/static_label_gen.rb +15 -0
  75. data/lib/rucc/t.rb +18 -0
  76. data/lib/rucc/tempname_gen.rb +14 -0
  77. data/lib/rucc/token.rb +114 -0
  78. data/lib/rucc/token_gen.rb +68 -0
  79. data/lib/rucc/type.rb +304 -0
  80. data/lib/rucc/type/check.rb +39 -0
  81. data/lib/rucc/type/conv.rb +29 -0
  82. data/lib/rucc/type_info.rb +21 -0
  83. data/lib/rucc/utf.rb +126 -0
  84. data/lib/rucc/util.rb +111 -0
  85. data/lib/rucc/version.rb +3 -0
  86. data/rucc.gemspec +38 -0
  87. metadata +201 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bed41186c5bd79a4ed10c8fbd408c33f17e0592fc9a17da1e1b9ab155c9ceefe
4
+ data.tar.gz: 708ac7987d181582dc317081509b8c957110a4a3a1a75b2ee98d353f6b885c8f
5
+ SHA512:
6
+ metadata.gz: efddbaa7e7b3a40156b55f4f7b6d89bbfabd4eddbf11a0eeb3acdea682e5c5942d5e496375c208d3498fcd1b4603eaf294f554298f549940aa9cdb2c4e816ac6
7
+ data.tar.gz: 8ff5b7183d0ffc49aad2de1d95f83e72cc8a78ea89436c0a5af8d8e43c7863b3f336742f66283b393b76148a3d1146b4988cbb84cabf310b82ec810b7ed916d6
@@ -0,0 +1,55 @@
1
+ # Only for development
2
+ thirdparty/*
3
+ .vagrant
4
+ tags
5
+
6
+ *.gem
7
+ *.rbc
8
+ /.config
9
+ /coverage/
10
+ /InstalledFiles
11
+ /pkg/
12
+ /spec/reports/
13
+ /spec/examples.txt
14
+ /test/tmp/
15
+ /test/version_tmp/
16
+ /tmp/
17
+
18
+ # Used by dotenv library to load environment variables.
19
+ # .env
20
+
21
+ ## Specific to RubyMotion:
22
+ .dat*
23
+ .repl_history
24
+ build/
25
+ *.bridgesupport
26
+ build-iPhoneOS/
27
+ build-iPhoneSimulator/
28
+
29
+ ## Specific to RubyMotion (use of CocoaPods):
30
+ #
31
+ # We recommend against adding the Pods directory to your .gitignore. However
32
+ # you should judge for yourself, the pros and cons are mentioned at:
33
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
34
+ #
35
+ # vendor/Pods/
36
+
37
+ ## Documentation cache and generated files:
38
+ /.yardoc/
39
+ /_yardoc/
40
+ /doc/
41
+ /rdoc/
42
+
43
+ ## Environment normalization:
44
+ /.bundle/
45
+ /vendor/bundle
46
+ /lib/bundler/man/
47
+
48
+ # for a library or gem, you might want to ignore these files since the code is
49
+ # intended to run in multiple environments; otherwise, check them in:
50
+ # Gemfile.lock
51
+ # .ruby-version
52
+ # .ruby-gemset
53
+
54
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
55
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.5.0
5
+ before_install: gem install bundler -v 1.16.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in rucc.gemspec
6
+ gemspec
@@ -0,0 +1,46 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rucc (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ byebug (9.1.0)
10
+ coderay (1.1.2)
11
+ diff-lcs (1.3)
12
+ method_source (0.9.0)
13
+ pry (0.11.3)
14
+ coderay (~> 1.1.0)
15
+ method_source (~> 0.9.0)
16
+ pry-byebug (3.5.1)
17
+ byebug (~> 9.1)
18
+ pry (~> 0.10)
19
+ rake (10.5.0)
20
+ rspec (3.7.0)
21
+ rspec-core (~> 3.7.0)
22
+ rspec-expectations (~> 3.7.0)
23
+ rspec-mocks (~> 3.7.0)
24
+ rspec-core (3.7.1)
25
+ rspec-support (~> 3.7.0)
26
+ rspec-expectations (3.7.0)
27
+ diff-lcs (>= 1.2.0, < 2.0)
28
+ rspec-support (~> 3.7.0)
29
+ rspec-mocks (3.7.0)
30
+ diff-lcs (>= 1.2.0, < 2.0)
31
+ rspec-support (~> 3.7.0)
32
+ rspec-support (3.7.0)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ bundler (~> 1.16)
39
+ pry
40
+ pry-byebug
41
+ rake (~> 10.0)
42
+ rspec (~> 3.7.0)
43
+ rucc!
44
+
45
+ BUNDLED WITH
46
+ 1.16.1
data/LICENCE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Nao Minami
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,82 @@
1
+ # Rucc
2
+
3
+ C compiler written in Ruby.
4
+
5
+ ## Project Goal
6
+
7
+ For learning about compiler, for creating hackable C compiler, for creating benchmark target of CRuby.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'rucc'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install rucc
24
+
25
+ ## Usage
26
+ `rucc` compiles c code and generates executable binary. Tested only in Linux (Ubuntu 17.04).
27
+
28
+ ```c
29
+ // hello.c
30
+
31
+ #include "stdio.h"
32
+
33
+ int main(int argc, char** argv) {
34
+ printf("Hello, World!\n");
35
+ }
36
+ ```
37
+
38
+ ```bash
39
+ $ rucc hello.c
40
+ $ ./a.out
41
+ Hello, World!
42
+ ```
43
+
44
+ By using `-S` or `-c` option, `rucc` generates assembly source code (`*.s`) and object file(`*.o`).
45
+
46
+ ```
47
+ $ rucc -S hello.c
48
+ $ ls
49
+ hello.c hello.s
50
+ ```
51
+
52
+ ```
53
+ $ rucc -c hello.c
54
+ $ ls
55
+ hello.c hello.o
56
+ ```
57
+
58
+
59
+ ## Development
60
+
61
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
62
+
63
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
64
+
65
+ ## TODO
66
+ - [ ] Add PIC support
67
+ - [ ] Build CRuby by rucc
68
+ - [ ] Refactor
69
+ - [ ] Add some CLI options
70
+ - [ ] Impl some features
71
+ - [ ] Support parentheses around function name
72
+
73
+ ## Contributing
74
+
75
+ Bug reports and pull requests are welcome on GitHub at https://github.com/south37/rucc.
76
+
77
+ ## License
78
+
79
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
80
+
81
+ ## Thanks
82
+ This project is highly inspired by [8cc](https://github.com/rui314/8cc). Thanks to rui314!
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,10 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ VAGRANTFILE_API_VERSION = "2"
5
+
6
+ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
7
+ config.vm.box = "bento/ubuntu-17.04"
8
+ config.vm.synced_folder "./", "/home/vagrant/rucc"
9
+ config.vm.synced_folder "./thirdparty/ruby", "/home/vagrant/ruby"
10
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rucc"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ require "pry"
10
+ Pry.start
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bash
2
+ bundle exec rspec $1
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rucc"
5
+
6
+ engine = Rucc::Engine.new(ARGV)
7
+ engine.run!
@@ -0,0 +1,48 @@
1
+ // Copyright 2014 Rui Ueyama. Released under the MIT license.
2
+
3
+ #define _LP64 1
4
+ #define __8cc__ 1
5
+ #define __ELF__ 1
6
+ #define __LP64__ 1
7
+ #define __SIZEOF_DOUBLE__ 8
8
+ #define __SIZEOF_FLOAT__ 4
9
+ #define __SIZEOF_INT__ 4
10
+ #define __SIZEOF_LONG_DOUBLE__ 8
11
+ #define __SIZEOF_LONG_LONG__ 8
12
+ #define __SIZEOF_LONG__ 8
13
+ #define __SIZEOF_POINTER__ 8
14
+ #define __SIZEOF_PTRDIFF_T__ 8
15
+ #define __SIZEOF_SHORT__ 2
16
+ #define __SIZEOF_SIZE_T__ 8
17
+ #define __STDC_HOSTED__ 1
18
+ #define __STDC_ISO_10646__ 201103L
19
+ #define __STDC_NO_ATOMICS__ 1
20
+ #define __STDC_NO_COMPLEX__ 1
21
+ #define __STDC_NO_THREADS__ 1
22
+ #define __STDC_NO_VLA__ 1
23
+ #define __STDC_UTF_16__ 1
24
+ #define __STDC_UTF_32__ 1
25
+ #define __STDC_VERSION__ 201112L
26
+ #define __STDC__ 1
27
+ #define __amd64 1
28
+ #define __amd64__ 1
29
+ #define __gnu_linux__ 1
30
+ #define __linux 1
31
+ #define __linux__ 1
32
+ #define __unix 1
33
+ #define __unix__ 1
34
+ #define __x86_64 1
35
+ #define __x86_64__ 1
36
+ #define linux 1
37
+
38
+ #define __alignof__ alignof
39
+ #define __const__ const
40
+ #define __inline__ inline
41
+ #define __restrict restrict
42
+ #define __restrict__ restrict
43
+ #define __signed__ signed
44
+ #define __typeof__ typeof
45
+ #define __volatile__ volatile
46
+
47
+ typedef unsigned short char16_t;
48
+ typedef unsigned int char32_t;
@@ -0,0 +1,44 @@
1
+ // Copyright 2014 Rui Ueyama. Released under the MIT license.
2
+
3
+ #ifndef __STDFLOAT_H
4
+ #define __STDFLOAT_H
5
+
6
+ #define DECIMAL_DIG 21
7
+ #define FLT_EVAL_METHOD 0 // C11 5.2.4.2.2p9
8
+ #define FLT_RADIX 2
9
+ #define FLT_ROUNDS 1 // C11 5.2.4.2.2p8: to nearest
10
+
11
+ #define FLT_DIG 6
12
+ #define FLT_EPSILON 0x1p-23
13
+ #define FLT_MANT_DIG 24
14
+ #define FLT_MAX 0x1.fffffep+127
15
+ #define FLT_MAX_10_EXP 38
16
+ #define FLT_MAX_EXP 128
17
+ #define FLT_MIN 0x1p-126
18
+ #define FLT_MIN_10_EXP -37
19
+ #define FLT_MIN_EXP -125
20
+ #define FLT_TRUE_MIN 0x1p-149
21
+
22
+ #define DBL_DIG 15
23
+ #define DBL_EPSILON 0x1p-52
24
+ #define DBL_MANT_DIG 53
25
+ #define DBL_MAX 0x1.fffffffffffffp+1023
26
+ #define DBL_MAX_10_EXP 308
27
+ #define DBL_MAX_EXP 1024
28
+ #define DBL_MIN 0x1p-1022
29
+ #define DBL_MIN_10_EXP -307
30
+ #define DBL_MIN_EXP -1021
31
+ #define DBL_TRUE_MIN 0x0.0000000000001p-1022
32
+
33
+ #define LDBL_DIG 15
34
+ #define LDBL_EPSILON 0x1p-52
35
+ #define LDBL_MANT_DIG 53
36
+ #define LDBL_MAX 0x1.fffffffffffffp+1023
37
+ #define LDBL_MAX_10_EXP 308
38
+ #define LDBL_MAX_EXP 1024
39
+ #define LDBL_MIN 0x1p-1022
40
+ #define LDBL_MIN_10_EXP -307
41
+ #define LDBL_MIN_EXP -1021
42
+ #define LDBL_TRUE_MIN 0x0.0000000000001p-1022
43
+
44
+ #endif
@@ -0,0 +1,20 @@
1
+ // Copyright 2014 Rui Ueyama. Released under the MIT license.
2
+
3
+ // C11 7.9 Alternative Spellings
4
+
5
+ #ifndef __ISO646_H
6
+ #define __ISO646_H
7
+
8
+ #define and &&
9
+ #define and_eq &=
10
+ #define bitand &
11
+ #define bitor |
12
+ #define compl ~
13
+ #define not !
14
+ #define not_eq !=
15
+ #define or ||
16
+ #define or_eq |=
17
+ #define xor ^
18
+ #define xor_eq ^=
19
+
20
+ #endif
@@ -0,0 +1,2 @@
1
+ #include "8cc.h"
2
+ #define __NO_INLINE__ 1
@@ -0,0 +1,11 @@
1
+ // Copyright 2012 Rui Ueyama. Released under the MIT license.
2
+
3
+ #ifndef __STDALIGN_H
4
+ #define __STDALIGN_H
5
+
6
+ #define alignas _Alignas
7
+ #define alignof _Alignof
8
+ #define __alignas_is_defined 1
9
+ #define __alignof_is_defined 1
10
+
11
+ #endif
@@ -0,0 +1,52 @@
1
+ // Copyright 2012 Rui Ueyama. Released under the MIT license.
2
+
3
+ #ifndef __STDARG_H
4
+ #define __STDARG_H
5
+
6
+ /**
7
+ * Refer this document for the x86-64 ABI.
8
+ * http://www.x86-64.org/documentation/abi.pdf
9
+ */
10
+
11
+ typedef struct {
12
+ unsigned int gp_offset;
13
+ unsigned int fp_offset;
14
+ void *overflow_arg_area;
15
+ void *reg_save_area;
16
+ } __va_elem;
17
+
18
+ typedef __va_elem va_list[1];
19
+
20
+ static void *__va_arg_gp(__va_elem *ap) {
21
+ void *r = (char *)ap->reg_save_area + ap->gp_offset;
22
+ ap->gp_offset += 8;
23
+ return r;
24
+ }
25
+
26
+ static void *__va_arg_fp(__va_elem *ap) {
27
+ void *r = (char *)ap->reg_save_area + ap->fp_offset;
28
+ ap->fp_offset += 16;
29
+ return r;
30
+ }
31
+
32
+ static void *__va_arg_mem(__va_elem *ap) {
33
+ 1 / 0; // unimplemented
34
+ }
35
+
36
+ #define va_start(ap, last) __builtin_va_start(ap)
37
+ #define va_arg(ap, type) \
38
+ ({ \
39
+ int klass = __builtin_reg_class((type *)0); \
40
+ *(type *)(klass == 0 ? __va_arg_gp(ap) : \
41
+ klass == 1 ? __va_arg_fp(ap) : \
42
+ __va_arg_mem(ap)); \
43
+ })
44
+
45
+ #define va_end(ap) 1
46
+ #define va_copy(dest, src) ((dest)[0] = (src)[0])
47
+
48
+ // Workaround to load stdio.h properly
49
+ #define __GNUC_VA_LIST 1
50
+ typedef va_list __gnuc_va_list;
51
+
52
+ #endif