Skip to content

Commit 073eddd

Browse files
committed
Refactor code generation
1 parent 14c1992 commit 073eddd

File tree

4 files changed

+157
-80
lines changed

4 files changed

+157
-80
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
extends Object
2+
3+
const Types = preload("res://addons/block_code/types/types.gd")
4+
const BlockAST = preload("res://addons/block_code/code_generation/block_ast.gd")
5+
6+
var array: Array[ASTPair]
7+
8+
9+
class ASTPair:
10+
var ast: BlockAST
11+
var canvas_position: Vector2
12+
13+
func _init(p_ast: BlockAST, p_canvas_position: Vector2):
14+
ast = p_ast
15+
canvas_position = p_canvas_position
16+
17+
18+
func _init():
19+
array = []
20+
21+
22+
func append(ast: BlockAST, canvas_position: Vector2):
23+
array.append(ASTPair.new(ast, canvas_position))
24+
25+
26+
func clear():
27+
array.clear()
28+
29+
30+
func get_top_level_nodes_of_type(block_type: Types.BlockType) -> Array[BlockAST]:
31+
var asts: Array[BlockAST] = []
32+
33+
for ast_pair in array:
34+
if ast_pair.ast.root.data.type == block_type:
35+
asts.append(ast_pair.ast)
36+
37+
return asts
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
extends Object
2+
3+
const BlockAST = preload("res://addons/block_code/code_generation/block_ast.gd")
4+
const Types = preload("res://addons/block_code/types/types.gd")
5+
6+
var root: ASTNode
7+
8+
9+
class ASTNode:
10+
var data #: BlockDefinition
11+
var children: Array[ASTNode]
12+
var arguments: Dictionary # String, ASTValueNode
13+
14+
func _init():
15+
children = []
16+
arguments = {}
17+
18+
func get_code_block() -> String:
19+
var code_block: String = data.code_template # get multiline code_template from block definition
20+
21+
# insert args
22+
23+
# check if args match an overload in the resource
24+
25+
for arg_name in arguments:
26+
# Use parentheses to be safe
27+
var argument = arguments[arg_name]
28+
var code_string: String
29+
if argument is ASTValueNode:
30+
code_string = argument.get_code()
31+
else:
32+
code_string = BlockAST.raw_input_to_code_string(argument)
33+
34+
code_block = code_block.replace("{%s}" % arg_name, code_string)
35+
36+
return code_block
37+
38+
func get_code(depth: int) -> String:
39+
var code: String = ""
40+
41+
# append code block
42+
var code_block := get_code_block()
43+
code_block = code_block.indent("\t".repeat(depth))
44+
45+
code += code_block + "\n"
46+
47+
# fill empty entry and control blocks with pass
48+
if children.is_empty() and (data.type == Types.BlockType.ENTRY || data.type == Types.BlockType.CONTROL):
49+
code += "pass\n".indent("\t".repeat(depth + 1))
50+
51+
for child in children:
52+
code += child.get_code(depth + 1)
53+
54+
return code
55+
56+
57+
class ASTValueNode:
58+
var data #: BlockDefinition
59+
var arguments: Dictionary # String, ASTValueNode
60+
61+
func _init():
62+
arguments = {}
63+
64+
func get_code() -> String:
65+
var code: String = data.code_template # get code_template from block definition
66+
67+
# check if args match an overload in the resource
68+
69+
for arg_name in arguments:
70+
# Use parentheses to be safe
71+
var argument = arguments[arg_name]
72+
var code_string: String
73+
if argument is ASTValueNode:
74+
code_string = argument.get_code()
75+
else:
76+
code_string = BlockAST.raw_input_to_code_string(argument)
77+
78+
code = code.replace("{%s}" % arg_name, code_string)
79+
80+
return "(%s)" % code
81+
82+
83+
func get_code() -> String:
84+
return root.get_code(0)
85+
86+
87+
func _to_string():
88+
return to_string_recursive(root, 0)
89+
90+
91+
func to_string_recursive(node: ASTNode, depth: int) -> String:
92+
var string: String = "%s %s\n" % ["-".repeat(depth), node.data.display_template]
93+
94+
for c in node.children:
95+
string += to_string_recursive(c, depth + 1)
96+
97+
return string
98+
99+
100+
static func raw_input_to_code_string(input) -> String:
101+
match typeof(input):
102+
TYPE_STRING:
103+
# HACK: don't include quotes around NIL strings
104+
if input.ends_with("__nil__"):
105+
return input.trim_suffix("__nil__")
106+
return "'%s'" % input.replace("\\", "\\\\").replace("'", "\\'")
107+
TYPE_VECTOR2:
108+
return "Vector2%s" % str(input)
109+
TYPE_COLOR:
110+
return "Color%s" % str(input)
111+
TYPE_OBJECT:
112+
if input is OptionData:
113+
var option_data := input as OptionData
114+
return option_data.items[option_data.selected]
115+
_:
116+
return "%s" % input
117+
118+
return ""

addons/block_code/code_generation/blocks_catalog.gd

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,8 @@ static var _catalog: Dictionary
77

88

99
static func setup():
10-
if _catalog:
11-
return
12-
13-
_catalog = {}
14-
var block_definition: BlockDefinition = BlockDefinition.new()
15-
block_definition.name = &"ready_block"
16-
block_definition.type = Types.BlockType.ENTRY
17-
block_definition.display_template = "On Ready"
18-
block_definition.code_template = "func _ready():"
19-
block_definition.description = 'Attached blocks will be executed once when the node is "ready"'
20-
block_definition.category = "Lifecycle"
21-
_catalog[&"ready_block"] = block_definition
22-
23-
block_definition = BlockDefinition.new()
24-
block_definition.name = &"print"
25-
block_definition.type = Types.BlockType.STATEMENT
26-
block_definition.display_template = "print {text: STRING}"
27-
block_definition.code_template = "print({text})"
28-
block_definition.defaults = {"text": "Hello"}
29-
block_definition.description = "Print the text to output"
30-
block_definition.category = "Log"
31-
_catalog[&"print"] = block_definition
10+
# Move dynamic block definitions here?
11+
pass
3212

3313

3414
static func get_block(block_name: StringName):

addons/block_code/instruction_tree/instruction_tree.gd

Lines changed: 0 additions & 58 deletions
This file was deleted.

0 commit comments

Comments
 (0)