burn 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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