burn 0.1.3 → 0.2.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 (56) hide show
  1. data/README.md +56 -569
  2. data/lib/burn.rb +5 -3
  3. data/lib/burn/cli.rb +160 -199
  4. data/lib/burn/config.rb +4 -0
  5. data/lib/burn/config/app.rb +15 -0
  6. data/lib/burn/config/config_base.rb +16 -0
  7. data/lib/burn/config/loader.rb +23 -0
  8. data/lib/burn/config/server.rb +11 -0
  9. data/lib/burn/fuel.rb +11 -0
  10. data/lib/burn/{dsl → fuel}/dsl_base.rb +1 -1
  11. data/lib/burn/fuel/rom/channel_stream.rb +106 -0
  12. data/lib/burn/fuel/rom/declare.rb +43 -0
  13. data/lib/burn/fuel/rom/music.rb +37 -0
  14. data/lib/burn/fuel/rom/note.rb +126 -0
  15. data/lib/burn/fuel/rom/scene.rb +279 -0
  16. data/lib/burn/fuel/rom/sound.rb +31 -0
  17. data/lib/burn/fuel/rom/sound_effect.rb +92 -0
  18. data/lib/burn/fuel/telnet/declare.rb +26 -0
  19. data/lib/burn/fuel/telnet/scene.rb +112 -0
  20. data/lib/burn/generator.rb +10 -3
  21. data/lib/burn/generator/rom/assembly_music.rb +49 -0
  22. data/lib/burn/generator/rom/assembly_sound_effect.rb +35 -0
  23. data/lib/burn/generator/rom/c_source.rb +55 -0
  24. data/lib/burn/generator/{template → rom/template}/mus_template.s +0 -0
  25. data/lib/burn/generator/{template → rom/template}/template.c +0 -0
  26. data/lib/burn/generator/rom_builder.rb +67 -0
  27. data/lib/burn/generator/telnet/jit_compiler.rb +41 -0
  28. data/lib/burn/generator/telnet/screen.rb +86 -0
  29. data/lib/burn/generator/telnet/sprite.rb +16 -0
  30. data/lib/burn/generator/telnet/user_input.rb +25 -0
  31. data/lib/burn/generator/telnet_vm.rb +50 -0
  32. data/lib/burn/pxes.rb +3 -0
  33. data/lib/burn/{util/pxes.rb → pxes/cc65_transpiler.rb} +8 -14
  34. data/lib/burn/pxes/cruby_transpiler.rb +189 -0
  35. data/lib/burn/pxes/transpiler_base.rb +14 -0
  36. data/lib/burn/server.rb +2 -0
  37. data/lib/burn/server/rom.rb +24 -0
  38. data/lib/burn/server/telnet.rb +120 -0
  39. data/lib/burn/util.rb +1 -2
  40. data/lib/burn/util/logo.rb +68 -0
  41. data/lib/burn/util/os.rb +1 -1
  42. data/lib/burn/version.rb +1 -1
  43. metadata +53 -19
  44. data/lib/burn/builder.rb +0 -65
  45. data/lib/burn/dsl.rb +0 -8
  46. data/lib/burn/dsl/channel_stream.rb +0 -105
  47. data/lib/burn/dsl/declare.rb +0 -42
  48. data/lib/burn/dsl/music.rb +0 -36
  49. data/lib/burn/dsl/note.rb +0 -125
  50. data/lib/burn/dsl/scene.rb +0 -278
  51. data/lib/burn/dsl/sound.rb +0 -30
  52. data/lib/burn/dsl/sound_effect.rb +0 -91
  53. data/lib/burn/generator/assembly_music.rb +0 -47
  54. data/lib/burn/generator/assembly_sound_effect.rb +0 -33
  55. data/lib/burn/generator/c_source.rb +0 -54
  56. data/lib/burn/util/server.rb +0 -21
@@ -0,0 +1,41 @@
1
+ module Burn
2
+ module Generator
3
+ module Telnet
4
+ class JitCompiler
5
+ include Fuel::Telnet
6
+ include Debug
7
+ attr_reader :opcodes
8
+
9
+ def initialize
10
+ @opcodes = Array.new
11
+ end
12
+
13
+ def get_context
14
+ self
15
+ end
16
+
17
+ def compile(source)
18
+ instance_eval source
19
+ @opcodes
20
+ end
21
+
22
+ def method_missing(method_symbol, *args, &block)
23
+ log :method_symbol=>method_symbol, :args=>args, :block=>block
24
+ if method_symbol == :scene then
25
+ # preprocess
26
+ args[0] = "main" if args[0].nil?
27
+
28
+ # execute dsls
29
+ @opcodes << "##{args[0]}"
30
+ Scene.new(args[0], self).instance_eval(&block)
31
+ @opcodes << "#END"
32
+
33
+ elsif method_symbol == :declare then
34
+ Declare.new(args[0], self).instance_eval(&block)
35
+
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,86 @@
1
+ module Burn
2
+ module Generator
3
+ module Telnet
4
+ class Screen
5
+ include Debug
6
+ ESC = 27.chr # equal to "\033"
7
+ CLEARSCREEN = ESC + "[2J"
8
+ JUMPTOHOME = ESC + "[H"
9
+ RESETALLATTR = ESC + "[0m"
10
+ CRLF = 13.chr + 10.chr
11
+
12
+ attr_accessor :display, :fg_color, :bg_color, :activated_sprite_objects
13
+
14
+ def initialize(conf)
15
+ @fg_color = 37
16
+ @bg_color = 40
17
+ @activated_sprite_objects = [] # activated sprite objects by #sprite method call during main_loop will be contained
18
+ @conf = conf
19
+ flush_screen
20
+ end
21
+
22
+ def to_terminal
23
+ #CLEARSCREEN + escape_color(@fg_color) + escape_color(@bg_color) + @display.join("\r\n") + JUMPTOHOME + RESETALLATTR
24
+ #JUMPTOHOME + RESETALLATTR + CLEARSCREEN + escape_color(@fg_color) + escape_color(@bg_color) + @display.join("\r\n") + ESC + "[#{@conf.app.height};2H" + RESETALLATTR
25
+ #CLEARSCREEN + escape_color(@fg_color) + escape_color(@bg_color) + @display.join("\r\n") + ESC + "[#{@conf.app.height};2H" + RESETALLATTR
26
+ #JUMPTOHOME + crlf + crlf + crlf + crlf + crlf + crlf + @display.join(crlf)
27
+ #JUMPTOHOME + crlf + crlf + crlf + crlf + crlf + crlf + @display.join(crlf) + crlf
28
+ #JUMPTOHOME + @display.join(CRLF) + CRLF
29
+
30
+ JUMPTOHOME + escape_color(@fg_color) + escape_color(@bg_color) + ppu_emulate + CRLF + RESETALLATTR
31
+ #JUMPTOHOME + @display.join(CRLF) + CRLF
32
+ end
33
+
34
+ def flush_screen
35
+ @display = Array.new
36
+ @conf.app.height.times{ @display << Array.new(@conf.app.width){' '}.join }
37
+ @activated_sprite_objects = []
38
+ end
39
+
40
+ def is_pressed(key, user_input)
41
+ log " ** program is waiting for:" + key.to_s
42
+ if !user_input.nil? then
43
+ log " **** confiremd user input:" + user_input.class.to_s, user_input.chr, user_input.to_s
44
+ if [*'0'..'9', *'a'..'z', *'A'..'Z'].include?(user_input.chr) && key.to_s == user_input.chr then
45
+ log "****** is_pressed() returned true"
46
+ return true
47
+ end
48
+ end
49
+ false
50
+ end
51
+
52
+ private
53
+
54
+ def escape_color(num)
55
+ ESC + "[" + num.to_s + ";1m"
56
+ end
57
+
58
+ def ppu_emulate
59
+ if @activated_sprite_objects.count == 0 then
60
+ @display.join(CRLF)
61
+ else
62
+ canvas = @display.map(&:dup) # deep copy
63
+ @activated_sprite_objects.each do |obj|
64
+ obj.tile.split("\n").each_with_index do |line, i|
65
+ canvas[(obj.y+ i) % @conf.app.height][obj.x % @conf.app.width,line.length] = line.chomp
66
+ end
67
+
68
+ # struct_var = "static sprite_schema #{key}={0, 0, {"
69
+ # @pattern_table_index[key.to_sym] = @pattern_table_pointer
70
+ # patternizer.patterns.each_with_index do |p, i|
71
+ # log p, i, patternizer.height, "aaaaaaaaaaaaaaaaaaa"
72
+ # struct_var += sprintf("%d, %d, %#x, 0,", (i % patternizer.width)*8 , (i / (patternizer.patterns.size / patternizer.height) )*8 , @pattern_table_pointer)
73
+ # @pattern_tables << p
74
+ # @pattern_table_pointer+=1
75
+ # end
76
+ # struct_var += "128}};"
77
+
78
+ end
79
+ canvas.join(CRLF)
80
+ end
81
+ end
82
+
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,16 @@
1
+ module Burn
2
+ module Generator
3
+ module Telnet
4
+ class Sprite
5
+ attr_accessor :tile, :x, :y
6
+
7
+ def initialize(tile, x, y)
8
+ @tile = tile
9
+ @x = x
10
+ @y = y
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ module Burn
2
+ module Generator
3
+ module Telnet
4
+ class UserInput
5
+ attr_reader :val
6
+
7
+ def initialize(conf)
8
+ @conf = conf
9
+ @signal = nil
10
+ @val = nil
11
+ end
12
+
13
+ def receive_signal(signal)
14
+ @signal = signal if @conf.app.user_input ==:enable
15
+ end
16
+
17
+ def init_for_next_loop
18
+ @val = @signal
19
+ @signal = nil
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,50 @@
1
+ module Burn
2
+ module Generator
3
+ class TelnetVm
4
+ include Generator::Telnet
5
+ include Debug
6
+ attr_reader :screen
7
+ attr_accessor :wait
8
+
9
+ def initialize(source, conf)
10
+ @pc = 0 # Program Counter
11
+ @screen = Screen.new(conf)
12
+ @wait = 10
13
+ @opcodes = JitCompiler.new.compile(source) # compiled methods
14
+ log @opcodes.join(":::")
15
+ @user_input = UserInput.new(conf)
16
+ @conf = conf
17
+ @finish = false
18
+ end
19
+
20
+ def next_frame
21
+ log @pc
22
+ if @wait > 0 then
23
+ @wait = @wait - 1
24
+ elsif !@finish then
25
+ log @user_input
26
+ if @opcodes[@pc] != "#END" && (@opcodes.count-1) > @pc then
27
+ @pc = @pc+1
28
+ # skipping comment out to speed up
29
+ while @opcodes[@pc-1][0] == '#' do
30
+ @pc = @pc+1
31
+ end
32
+ log @opcodes[@pc-1]
33
+ self.instance_eval @opcodes[@pc-1]
34
+ else
35
+ log "Program counter reached at the end of program. #END"
36
+ @finish = true
37
+ end
38
+ else # if @finish == true then
39
+ # do nothing
40
+ end
41
+ end
42
+
43
+ def interrupt(signal)
44
+ log "INTTERUPT_SETTING:" + @conf.app.user_input.to_s
45
+ @user_input.receive_signal(signal)
46
+ end
47
+
48
+ end
49
+ end
50
+ end
data/lib/burn/pxes.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'burn/pxes/transpiler_base'
2
+ require 'burn/pxes/cc65_transpiler'
3
+ require 'burn/pxes/cruby_transpiler'
@@ -1,14 +1,6 @@
1
1
  module Burn
2
- module Util
3
- class Pxes
4
- include Debug
5
- attr_reader :sexp
6
-
7
- def initialize(sexp, context=nil, resource_name=nil)
8
- @sexp = sexp
9
- @context = context || self
10
- @resource_name = resource_name
11
- end
2
+ module Pxes
3
+ class Cc65Transpiler < TranspilerBase
12
4
 
13
5
  def to_c
14
6
  parse_sexp(@sexp)
@@ -27,9 +19,10 @@ module Burn
27
19
  # end
28
20
  #end
29
21
 
22
+
30
23
  def invoke_dsl_processing(exp)
31
- generator = Generator::CSource.new(self)
32
- Dsl::Scene.new(@resource_name, generator).instance_eval exp
24
+ generator = Generator::Rom::CSource.new(self)
25
+ Fuel::Rom::Scene.new(@resource_name, generator).instance_eval exp
33
26
  # return the result
34
27
  @context.instance_exec(generator.global) do |generator_global|
35
28
  @global.concat generator_global
@@ -100,14 +93,14 @@ module Burn
100
93
 
101
94
  # this is why you can't use pre-defined dsl name as a variable name. e.g) you are not allowed to declare variables like show or label or stop. these all are defined dsl.
102
95
  when :vcall
103
- if !Dsl::Scene.new(@resource_name,self).methods.index(s[1][1].to_sym).nil? then
96
+ if !Fuel::Rom::Scene.new(@resource_name,self).methods.index(s[1][1].to_sym).nil? then
104
97
  invoke_dsl_processing parse_sexp(s[1])
105
98
  else
106
99
  parse_sexp(s[1])
107
100
  end
108
101
 
109
102
  when :command
110
- if !Dsl::Scene.new(@resource_name,self).methods.index(s[1][1].to_sym).nil? then
103
+ if !Fuel::Rom::Scene.new(@resource_name,self).methods.index(s[1][1].to_sym).nil? then
111
104
  #invoke_dsl_processing parse_sexp(s[1]) + "(" + parse_sexp( replace_vcall_to_symbol(s[2]) ) + ")"
112
105
  invoke_dsl_processing parse_sexp(s[1]) + "(" + parse_sexp( s[2] ) + ")"
113
106
  else
@@ -175,6 +168,7 @@ module Burn
175
168
  log s[0].class.to_s
176
169
  end
177
170
  end
171
+
178
172
  end
179
173
  end
180
174
  end
@@ -0,0 +1,189 @@
1
+ module Burn
2
+ module Pxes
3
+ class CrubyTranspiler < TranspilerBase
4
+
5
+ def to_rb
6
+ parse_sexp(@sexp)
7
+ end
8
+
9
+ private
10
+ #def replace_vcall_to_symbol(sexp_array)
11
+ # sexp_array.map do |a|
12
+ # if a.instance_of?(Array) then
13
+ # replace_vcall_to_symbol(a)
14
+ # elsif a==:vcall then
15
+ # :symbol
16
+ # else
17
+ # a
18
+ # end
19
+ # end
20
+ #end
21
+
22
+ def invoke_dsl_processing(exp)
23
+ generator = Generator::Telnet::JitCompiler.new
24
+ # class(@@)|instance(@) variable inside exp need to be stringified before the #instance_eval.
25
+ # Without this, variables will be evaluated immediately now (and will get disappered as a result of this) by #instance_eval
26
+ Fuel::Telnet::Scene.new(@resource_name, generator).instance_eval exp.gsub(/(@[@\w]*)/, "\"\\1\"")
27
+ generator.opcodes.join "\n"
28
+ end
29
+
30
+ def parse_sexp(s)
31
+ if s.instance_of?(String) then
32
+ s
33
+ elsif s.instance_of?(Array) && s[0].instance_of?(Symbol) then
34
+ log "--array and symbol--"
35
+ log s[0]
36
+ case s[0]
37
+ when :assign
38
+ parse_sexp(s[1]) + "=" + parse_sexp(s[2])
39
+
40
+ when :var_field, :var_ref
41
+ if s[1][0] == :@ident then
42
+ var_scope = "@___"
43
+ else
44
+ var_scope = ""
45
+ end
46
+ var_scope + s[1][1]
47
+
48
+ when :void_stmt
49
+ "" # this happens when rip "if true then # do nothing end" type of code
50
+
51
+ when :binary
52
+ case s[2]
53
+ when :or
54
+ operator = "||"
55
+ when :and
56
+ operator = "&&"
57
+ else
58
+ operator = s[2].to_s
59
+ end
60
+ parse_sexp(s[1]) + operator + parse_sexp(s[3])
61
+
62
+ when :opassign
63
+ parse_sexp(s[1]) + parse_sexp(s[2]) + parse_sexp(s[3])
64
+
65
+ when :unary
66
+ case s[1]
67
+ when :not, :!
68
+ "!" + parse_sexp(s[2])
69
+ else
70
+ parse_sexp(s[2])
71
+ end
72
+
73
+ when :paren
74
+ "(" + parse_sexp(s[1][0]) + ")"
75
+
76
+ when :symbol
77
+ ':' + s[1][1]
78
+
79
+ when :field, :call
80
+ parse_sexp(s[1]) + "." + parse_sexp(s[3])
81
+
82
+ when :@ident, :@int, :@kw, :@op
83
+ s[1]
84
+
85
+ when :@tstring_content
86
+ '"' + s[1] + '"'
87
+
88
+ # this is why you can't use pre-defined dsl name as a variable name. e.g) you are not allowed to declare variables like show or label or stop. these all are defined dsl.
89
+ when :vcall
90
+ if s[1][0] == :@ident then
91
+ var_scope = "@___"
92
+ else
93
+ var_scope = ""
94
+ end
95
+ s[1][1] = var_scope + s[1][1]
96
+ parse_sexp(s[1])
97
+
98
+ # this is why you can't use pre-defined dsl name as a variable name. e.g) you are not allowed to declare variables like show or label or stop. these all are defined dsl.
99
+ when :command
100
+ if !Fuel::Telnet::Scene.new(@resource_name,@context).methods.index(s[1][1].to_sym).nil? then
101
+ #invoke_dsl_processing parse_sexp(s[1]) + "(" + parse_sexp( replace_vcall_to_symbol(s[2]) ) + ")"
102
+ invoke_dsl_processing parse_sexp(s[1]) + "(" + parse_sexp( s[2] ) + ")"
103
+ else
104
+ parse_sexp(s[1]) + "(" + parse_sexp(s[2]) + ")"
105
+ end
106
+
107
+ when :method_add_arg
108
+ command = s[1][1][1]
109
+ # check if it matches dsl.
110
+ case command
111
+ when "is_pressed"
112
+ "@screen.is_pressed(" + parse_sexp(s[2]) + ", @user_input.val)"
113
+ #when "rand"
114
+ # parse_sexp(s[1]) + "8()"
115
+ else
116
+ parse_sexp(s[1]) + "(" + parse_sexp(s[2]) + ")"
117
+ end
118
+
119
+ # Currently pssing block is not supported
120
+ #when :method_add_block
121
+
122
+ when :args_add_block
123
+ a = Array.new
124
+ s[1].each_with_index do |sexp,i|
125
+ log "<<<<<<<<<<<<<<<<<<NUM #{i}>>>>>>"
126
+ log sexp
127
+ a << parse_sexp(sexp)
128
+ end
129
+ a.join(",")
130
+
131
+ when :while
132
+ "while(" + parse_sexp(s[1]) + "){" + parse_sexp(s[2]) + "}"
133
+
134
+ when :if, :if_mod, :elsif
135
+ if s[0]==:elsif then
136
+ keyword = "else if"
137
+ else
138
+ keyword = "if"
139
+ end
140
+ additional_condition = parse_sexp(s[3]) if !s[3].nil?
141
+ #"#{keyword} (" + parse_sexp(s[1]) + "){" + parse_sexp(s[2]) + "} #{additional_condition}"
142
+ label = "##{@resource_name}-" + [*0-9, *'a'..'z', *'A'..'Z'].sample(10).join
143
+ #"@pc = @opcodes.index(\"#{label}\") if !(" + parse_sexp(s[1]) + ")\n" + parse_sexp(s[2]) + "\n#{label}"
144
+ if additional_condition then
145
+ # jump to else
146
+ # + script for if clause
147
+ # jump to end
148
+ # label for else
149
+ # + script for else
150
+ # label for end
151
+ "@pc = @opcodes.index(\"#{label}\") if !(" + parse_sexp(s[1]) + ")\n" \
152
+ + parse_sexp(s[2]) + "\n" \
153
+ + "@pc = @opcodes.index(\"#{label}-else\")\n" \
154
+ + "#{label}\n" \
155
+ + additional_condition + "\n" \
156
+ + "#{label}-else"
157
+ else
158
+ "@pc = @opcodes.index(\"#{label}\") if !(" + parse_sexp(s[1]) + ")\n" + parse_sexp(s[2]) + "\n#{label}"
159
+ end
160
+
161
+
162
+ #when :def
163
+ # is not supported for to_c as return data type cannot be defined
164
+
165
+ when :else
166
+ parse_sexp(s[1])
167
+
168
+ else
169
+ parse_sexp(s[1])
170
+
171
+ end
172
+ # Safety net
173
+ elsif s.instance_of?(Array) && s[0].instance_of?(Array) then
174
+ a = Array.new
175
+ s.each_with_index do |sexp,i|
176
+ log "<<<<<<<<<<<<<<<<<<NUM #{i}>>>>>>"
177
+ log sexp
178
+ a << parse_sexp(sexp)
179
+ end
180
+ a.join("\n")
181
+ else
182
+ log "--else--"
183
+ log s.class.to_s
184
+ log s[0].class.to_s
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end