├── docker ├── init │ ├── run.sh │ └── Dockerfile ├── update │ ├── run.sh │ └── Dockerfile ├── update.sh ├── init.sh └── run.sh ├── bin ├── gds.gd.uid ├── gds.gd └── gds.tscn ├── zigcc ├── addons └── gdUnit4 ├── gdsbin ├── ast.gd.uid ├── defs.gd.uid ├── extend.gd.uid ├── file.gd.uid ├── key.gd.uid ├── props.gd.uid ├── root.gd.uid ├── token.gd.uid ├── __init__.gd.uid ├── __main__.gd.uid ├── callnew.gd.uid ├── classn.gd.uid ├── comment.gd.uid ├── forloop.gd.uid ├── function.gd.uid ├── ifcond.gd.uid ├── keyword.gd.uid ├── parsertree.gd.uid ├── run_button.gd.uid ├── stringname.gd.uid ├── test │ ├── enums.gd.uid │ ├── ins.gd.uid │ ├── whiles.gd.uid │ ├── __init__.gd.uid │ ├── arrays.gd.uid │ ├── benchmark.gd.uid │ ├── constants.gd.uid │ ├── for_range.gd.uid │ ├── matches.gd.uid │ ├── nested_if.gd.uid │ ├── truthiness.gd.uid │ ├── concatenation.gd.uid │ ├── dictionaries.gd.uid │ ├── export_variable.gd.uid │ ├── float_notation.gd.uid │ ├── if_after_lambda.gd.uid │ ├── lambda_callable.gd.uid │ ├── match_dictionary.gd.uid │ ├── multiline_if.gd.uid │ ├── nested_array.gd.uid │ ├── nested_match.gd.uid │ ├── operator_assign.gd.uid │ ├── static_typing.gd.uid │ ├── typed_arrays.gd.uid │ ├── bitwise_operators.gd.uid │ ├── dictionary_lua_style.gd.uid │ ├── dollar_node_paths.gd.uid │ ├── match_bind_unused.gd.uid │ ├── multiline_arrays.gd.uid │ ├── multiline_strings.gd.uid │ ├── multiline_vector.gd.uid │ ├── nested_arithmetic.gd.uid │ ├── nested_dictionary.gd.uid │ ├── nested_parentheses.gd.uid │ ├── number_separators.gd.uid │ ├── signal_declaration.gd.uid │ ├── str_preserves_case.gd.uid │ ├── string_formatting.gd.uid │ ├── variable_declaration.gd.uid │ ├── basic_expression_matching.gd.uid │ ├── dictionary_mixed_syntax.gd.uid │ ├── function_many_parameters.gd.uid │ ├── lambda_capture_callable.gd.uid │ ├── lambda_named_callable.gd.uid │ ├── multiline_dictionaries.gd.uid │ ├── nested_function_calls.gd.uid │ ├── property_setter_getter.gd.uid │ ├── semicolon_as_terminator.gd.uid │ ├── advanced_expression_matching.gd.uid │ ├── dollar_and_percent_get_node.gd.uid │ ├── semicolon_as_end_statement.gd.uid │ ├── arrays_dictionaries_nested_const.gd.uid │ ├── lambda_default_parameter_capture.gd.uid │ ├── match_multiple_patterns_with_array.gd.uid │ ├── trailing_comma_in_function_args.gd.uid │ ├── function_default_parameter_type_inference.gd.uid │ ├── match_multiple_variable_binds_in_pattern.gd.uid │ ├── whiles.gd │ ├── concatenation.gd │ ├── lambda_callable.gd │ ├── __init__.gd │ ├── lambda_capture_callable.gd │ ├── operator_assign.gd │ ├── multiline_arrays.gd │ ├── typed_arrays.gd │ ├── if_after_lambda.gd │ ├── match_multiple_variable_binds_in_pattern.gd │ ├── semicolon_as_end_statement.gd │ ├── function_default_parameter_type_inference.gd │ ├── nested_array.gd │ ├── enums.gd │ ├── str_preserves_case.gd │ ├── nested_function_calls.gd │ ├── trailing_comma_in_function_args.gd │ ├── lambda_default_parameter_capture.gd │ ├── multiline_vector.gd │ ├── multiline_dictionaries.gd │ ├── dictionary_lua_style.gd │ ├── multiline_if.gd │ ├── dictionary_mixed_syntax.gd │ ├── lambda_named_callable.gd │ ├── nested_dictionary.gd │ ├── signal_declaration.gd │ ├── constants.gd │ ├── semicolon_as_terminator.gd │ ├── match_bind_unused.gd │ ├── matches.gd │ ├── ins.gd │ ├── export_variable.gd │ ├── arrays.gd │ ├── static_typing.gd │ ├── match_multiple_patterns_with_array.gd │ ├── number_separators.gd │ ├── variable_declaration.gd │ ├── basic_expression_matching.gd │ ├── dollar_node_paths.gd │ ├── for_range.gd │ ├── multiline_strings.gd │ ├── string_formatting.gd │ ├── advanced_expression_matching.gd │ ├── property_setter_getter.gd │ ├── function_many_parameters.gd │ ├── truthiness.gd │ ├── float_notation.gd │ ├── bitwise_operators.gd │ ├── nested_arithmetic.gd │ ├── match_dictionary.gd │ ├── dictionaries.gd │ ├── dollar_and_percent_get_node.gd │ ├── arrays_dictionaries_nested_const.gd │ ├── nested_if.gd │ ├── nested_match.gd │ ├── nested_parentheses.gd │ └── benchmark.gd ├── tokenizer.gd.uid ├── transpiler.gd.uid ├── variable.gd.uid ├── vector2.gd.uid ├── version.gd.uid ├── application.gd.uid ├── dictionaryname.gd.uid ├── main_window.gd.uid ├── script_editor.gd.uid ├── variant_type.gd.uid ├── variant_operator.gd.uid ├── fonts │ ├── hack_regular.ttf │ ├── noto_sans_regular.ttf │ ├── hack_regular.ttf.import │ ├── noto_sans_regular.ttf.import │ ├── LICENSE.Hack.md │ └── LICENSE.Noto.txt ├── token.gd ├── root.gd ├── version.gd ├── ifcond.gd ├── classn.gd ├── comment.gd ├── extend.gd ├── forloop.gd ├── stringname.gd ├── dictionaryname.gd ├── function.gd ├── variable.gd ├── callnew.gd ├── keyword.gd ├── run_button.gd ├── main_window.gd ├── __init__.gd ├── application.gd ├── variant_operator.gd ├── file.gd ├── variant_type.gd ├── defs.gd ├── tokenizer.gd ├── main.tscn ├── resources │ └── theme.tres ├── parsertree.gd ├── key.gd ├── vector2.gd ├── script_editor.gd ├── ast.gd └── transpiler.gd ├── zigc++ ├── .editorconfig ├── preview.gif ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ └── config.yml └── dependabot.yml ├── .gitmodules ├── icon.svg ├── .forgejo ├── ISSUE_TEMPLATE │ ├── request.md │ └── bug.md └── workflows │ ├── upload.yml │ └── template.yml ├── .gitignore ├── mit.svg ├── python.svg ├── LICENSE.md ├── icon.svg.import ├── mit.svg.import ├── python.svg.import ├── Godot-v.svg.import ├── Godot-v.svg ├── project.godot ├── CONTRIBUTING.md └── README.md /docker/init/run.sh: -------------------------------------------------------------------------------- 1 | ../run.sh -------------------------------------------------------------------------------- /docker/update/run.sh: -------------------------------------------------------------------------------- 1 | ../run.sh -------------------------------------------------------------------------------- /bin/gds.gd.uid: -------------------------------------------------------------------------------- 1 | uid://djndy44dugvay 2 | -------------------------------------------------------------------------------- /zigcc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | $ZIG_EXE cc $@ 3 | -------------------------------------------------------------------------------- /addons/gdUnit4: -------------------------------------------------------------------------------- 1 | ../gdUnit4/addons/gdUnit4 -------------------------------------------------------------------------------- /gdsbin/ast.gd.uid: -------------------------------------------------------------------------------- 1 | uid://b15wyodq1i4i 2 | -------------------------------------------------------------------------------- /gdsbin/defs.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bqxi8t3f1m0rv 2 | -------------------------------------------------------------------------------- /gdsbin/extend.gd.uid: -------------------------------------------------------------------------------- 1 | uid://e8722vgeimeb 2 | -------------------------------------------------------------------------------- /gdsbin/file.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dk2x0lyffy3r7 2 | -------------------------------------------------------------------------------- /gdsbin/key.gd.uid: -------------------------------------------------------------------------------- 1 | uid://daneo54qh4oi6 2 | -------------------------------------------------------------------------------- /gdsbin/props.gd.uid: -------------------------------------------------------------------------------- 1 | uid://3ssmu0c1hn37 2 | -------------------------------------------------------------------------------- /gdsbin/root.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bip3n1c1vuc7c 2 | -------------------------------------------------------------------------------- /gdsbin/token.gd.uid: -------------------------------------------------------------------------------- 1 | uid://disf1rtybr7ph 2 | -------------------------------------------------------------------------------- /zigc++: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | $ZIG_EXE c++ $@ 3 | -------------------------------------------------------------------------------- /gdsbin/__init__.gd.uid: -------------------------------------------------------------------------------- 1 | uid://drcfe6ykjbk3c 2 | -------------------------------------------------------------------------------- /gdsbin/__main__.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dldbkyhw6o5xt 2 | -------------------------------------------------------------------------------- /gdsbin/callnew.gd.uid: -------------------------------------------------------------------------------- 1 | uid://b8rskkvv6m45r 2 | -------------------------------------------------------------------------------- /gdsbin/classn.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bf02ft12o5o5s 2 | -------------------------------------------------------------------------------- /gdsbin/comment.gd.uid: -------------------------------------------------------------------------------- 1 | uid://8n3d3xxn0oli 2 | -------------------------------------------------------------------------------- /gdsbin/forloop.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bgdt7lj11vnbq 2 | -------------------------------------------------------------------------------- /gdsbin/function.gd.uid: -------------------------------------------------------------------------------- 1 | uid://b0ocn8hg14h43 2 | -------------------------------------------------------------------------------- /gdsbin/ifcond.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c7f7yrl5uo5sc 2 | -------------------------------------------------------------------------------- /gdsbin/keyword.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bb4kb33grgfgw 2 | -------------------------------------------------------------------------------- /gdsbin/parsertree.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c380bf5pgkuul 2 | -------------------------------------------------------------------------------- /gdsbin/run_button.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c4qpli2ohyfbj 2 | -------------------------------------------------------------------------------- /gdsbin/stringname.gd.uid: -------------------------------------------------------------------------------- 1 | uid://4vmt58tvh8up 2 | -------------------------------------------------------------------------------- /gdsbin/test/enums.gd.uid: -------------------------------------------------------------------------------- 1 | uid://0ad3kwnxf3j5 2 | -------------------------------------------------------------------------------- /gdsbin/test/ins.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cyhl3p5yumy5t 2 | -------------------------------------------------------------------------------- /gdsbin/test/whiles.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ntmwrs1mfhnd 2 | -------------------------------------------------------------------------------- /gdsbin/tokenizer.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dutcq7dv2l5fb 2 | -------------------------------------------------------------------------------- /gdsbin/transpiler.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c4equ77l8h1uu 2 | -------------------------------------------------------------------------------- /gdsbin/variable.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dklw14bdeoe6b 2 | -------------------------------------------------------------------------------- /gdsbin/vector2.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cakqtwb0mg0s7 2 | -------------------------------------------------------------------------------- /gdsbin/version.gd.uid: -------------------------------------------------------------------------------- 1 | uid://jbkrs7c2eg21 2 | -------------------------------------------------------------------------------- /gdsbin/application.gd.uid: -------------------------------------------------------------------------------- 1 | uid://do8nlayda8371 2 | -------------------------------------------------------------------------------- /gdsbin/dictionaryname.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cv3xyyjudn0f3 2 | -------------------------------------------------------------------------------- /gdsbin/main_window.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c56mduespamfh 2 | -------------------------------------------------------------------------------- /gdsbin/script_editor.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dq0ro428q1yxf 2 | -------------------------------------------------------------------------------- /gdsbin/test/__init__.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dsovqwoqpw57y 2 | -------------------------------------------------------------------------------- /gdsbin/test/arrays.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bswgw255j3op6 2 | -------------------------------------------------------------------------------- /gdsbin/test/benchmark.gd.uid: -------------------------------------------------------------------------------- 1 | uid://de3p1gwpn5csl 2 | -------------------------------------------------------------------------------- /gdsbin/test/constants.gd.uid: -------------------------------------------------------------------------------- 1 | uid://d2eggnvwob3rs 2 | -------------------------------------------------------------------------------- /gdsbin/test/for_range.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dsvhr1vn25vy2 2 | -------------------------------------------------------------------------------- /gdsbin/test/matches.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bf7qg4omcv87k 2 | -------------------------------------------------------------------------------- /gdsbin/test/nested_if.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c14p0rh161o7s 2 | -------------------------------------------------------------------------------- /gdsbin/test/truthiness.gd.uid: -------------------------------------------------------------------------------- 1 | uid://deekmbg5rxoh5 2 | -------------------------------------------------------------------------------- /gdsbin/variant_type.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dfabuc1q51oot 2 | -------------------------------------------------------------------------------- /gdsbin/test/concatenation.gd.uid: -------------------------------------------------------------------------------- 1 | uid://0bqvkifap553 2 | -------------------------------------------------------------------------------- /gdsbin/test/dictionaries.gd.uid: -------------------------------------------------------------------------------- 1 | uid://u2o8pxf1y5mx 2 | -------------------------------------------------------------------------------- /gdsbin/test/export_variable.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cbj7kaudnvmlf 2 | -------------------------------------------------------------------------------- /gdsbin/test/float_notation.gd.uid: -------------------------------------------------------------------------------- 1 | uid://beja7flqq8olp 2 | -------------------------------------------------------------------------------- /gdsbin/test/if_after_lambda.gd.uid: -------------------------------------------------------------------------------- 1 | uid://b4bn2rv2pqshh 2 | -------------------------------------------------------------------------------- /gdsbin/test/lambda_callable.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bobot5336ulh6 2 | -------------------------------------------------------------------------------- /gdsbin/test/match_dictionary.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ejxa43jsfhwr 2 | -------------------------------------------------------------------------------- /gdsbin/test/multiline_if.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cw2q38eqoaep5 2 | -------------------------------------------------------------------------------- /gdsbin/test/nested_array.gd.uid: -------------------------------------------------------------------------------- 1 | uid://deh38l671xpei 2 | -------------------------------------------------------------------------------- /gdsbin/test/nested_match.gd.uid: -------------------------------------------------------------------------------- 1 | uid://hdswv0ypltf2 2 | -------------------------------------------------------------------------------- /gdsbin/test/operator_assign.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bw0mfr8goj4mn 2 | -------------------------------------------------------------------------------- /gdsbin/test/static_typing.gd.uid: -------------------------------------------------------------------------------- 1 | uid://3sfcic2ben2u 2 | -------------------------------------------------------------------------------- /gdsbin/test/typed_arrays.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dl32ro1s5ovmt 2 | -------------------------------------------------------------------------------- /gdsbin/variant_operator.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dlrnx1mr0qqyv 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | -------------------------------------------------------------------------------- /gdsbin/test/bitwise_operators.gd.uid: -------------------------------------------------------------------------------- 1 | uid://buh5ghqf4q6sm 2 | -------------------------------------------------------------------------------- /gdsbin/test/dictionary_lua_style.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c7go7hevvfwyv 2 | -------------------------------------------------------------------------------- /gdsbin/test/dollar_node_paths.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bpai8nua4ghvl 2 | -------------------------------------------------------------------------------- /gdsbin/test/match_bind_unused.gd.uid: -------------------------------------------------------------------------------- 1 | uid://mucgionmg8x8 2 | -------------------------------------------------------------------------------- /gdsbin/test/multiline_arrays.gd.uid: -------------------------------------------------------------------------------- 1 | uid://beu7bpb6rvnfe 2 | -------------------------------------------------------------------------------- /gdsbin/test/multiline_strings.gd.uid: -------------------------------------------------------------------------------- 1 | uid://de8nw8dyfflkr 2 | -------------------------------------------------------------------------------- /gdsbin/test/multiline_vector.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cb5dkbo70n1e7 2 | -------------------------------------------------------------------------------- /gdsbin/test/nested_arithmetic.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dpsb0igy22vnj 2 | -------------------------------------------------------------------------------- /gdsbin/test/nested_dictionary.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ch4goriunupnp 2 | -------------------------------------------------------------------------------- /gdsbin/test/nested_parentheses.gd.uid: -------------------------------------------------------------------------------- 1 | uid://f73e2yh038mu 2 | -------------------------------------------------------------------------------- /gdsbin/test/number_separators.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c3w6nhpyt4uce 2 | -------------------------------------------------------------------------------- /gdsbin/test/signal_declaration.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dymjl52fanoks 2 | -------------------------------------------------------------------------------- /gdsbin/test/str_preserves_case.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c804j7wg3lrfb 2 | -------------------------------------------------------------------------------- /gdsbin/test/string_formatting.gd.uid: -------------------------------------------------------------------------------- 1 | uid://6ygl747yifis 2 | -------------------------------------------------------------------------------- /gdsbin/test/variable_declaration.gd.uid: -------------------------------------------------------------------------------- 1 | uid://825fen7rginr 2 | -------------------------------------------------------------------------------- /gdsbin/test/basic_expression_matching.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bsq4j0u1abmal 2 | -------------------------------------------------------------------------------- /gdsbin/test/dictionary_mixed_syntax.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dqwwot1qw5g2t 2 | -------------------------------------------------------------------------------- /gdsbin/test/function_many_parameters.gd.uid: -------------------------------------------------------------------------------- 1 | uid://828yjaae16m2 2 | -------------------------------------------------------------------------------- /gdsbin/test/lambda_capture_callable.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cc8iyv0tsk3pu 2 | -------------------------------------------------------------------------------- /gdsbin/test/lambda_named_callable.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bwx00dtw5ytmk 2 | -------------------------------------------------------------------------------- /gdsbin/test/multiline_dictionaries.gd.uid: -------------------------------------------------------------------------------- 1 | uid://b6vcjfx1243qy 2 | -------------------------------------------------------------------------------- /gdsbin/test/nested_function_calls.gd.uid: -------------------------------------------------------------------------------- 1 | uid://b74tkaolu8hd6 2 | -------------------------------------------------------------------------------- /gdsbin/test/property_setter_getter.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cbfx7fi38ntk1 2 | -------------------------------------------------------------------------------- /gdsbin/test/semicolon_as_terminator.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ddclubos1usb 2 | -------------------------------------------------------------------------------- /gdsbin/test/advanced_expression_matching.gd.uid: -------------------------------------------------------------------------------- 1 | uid://coprqgxss2f0q 2 | -------------------------------------------------------------------------------- /gdsbin/test/dollar_and_percent_get_node.gd.uid: -------------------------------------------------------------------------------- 1 | uid://vrhc7ce2y0we 2 | -------------------------------------------------------------------------------- /gdsbin/test/semicolon_as_end_statement.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dhgqkr0wq1ire 2 | -------------------------------------------------------------------------------- /gdsbin/test/arrays_dictionaries_nested_const.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dqs6fy7l4c03c 2 | -------------------------------------------------------------------------------- /gdsbin/test/lambda_default_parameter_capture.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cblj3doyd1y04 2 | -------------------------------------------------------------------------------- /gdsbin/test/match_multiple_patterns_with_array.gd.uid: -------------------------------------------------------------------------------- 1 | uid://chm8wc6jsercf 2 | -------------------------------------------------------------------------------- /gdsbin/test/trailing_comma_in_function_args.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cpeb6itnl7ogg 2 | -------------------------------------------------------------------------------- /gdsbin/test/function_default_parameter_type_inference.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ln36qff5ny7f 2 | -------------------------------------------------------------------------------- /gdsbin/test/match_multiple_variable_binds_in_pattern.gd.uid: -------------------------------------------------------------------------------- 1 | uid://kkboey35f8lj 2 | -------------------------------------------------------------------------------- /preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxUserGD/gdscript-transpiler-bin/HEAD/preview.gif -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Normalize EOL for all files that Git considers text files. 2 | * text=auto eol=lf 3 | -------------------------------------------------------------------------------- /gdsbin/test/whiles.gd: -------------------------------------------------------------------------------- 1 | class_name Whiles 2 | 3 | func test(): 4 | var i = 0 5 | while i < 5: 6 | print(i) 7 | i += 1 8 | -------------------------------------------------------------------------------- /gdsbin/fonts/hack_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxUserGD/gdscript-transpiler-bin/HEAD/gdsbin/fonts/hack_regular.ttf -------------------------------------------------------------------------------- /gdsbin/fonts/noto_sans_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxUserGD/gdscript-transpiler-bin/HEAD/gdsbin/fonts/noto_sans_regular.ttf -------------------------------------------------------------------------------- /gdsbin/test/concatenation.gd: -------------------------------------------------------------------------------- 1 | class_name Concatenation 2 | 3 | func test(): 4 | print(20 + 20) 5 | print("hello" + "world") 6 | print([1, 2] + [3, 4]) 7 | -------------------------------------------------------------------------------- /gdsbin/test/lambda_callable.gd: -------------------------------------------------------------------------------- 1 | class_name Lambda_callable 2 | 3 | func test(): 4 | var my_lambda = func(x): 5 | print(x) 6 | my_lambda.call("hello") 7 | -------------------------------------------------------------------------------- /gdsbin/test/__init__.gd: -------------------------------------------------------------------------------- 1 | ## GDScript Init Dummy File 2 | ## 3 | ## Dummy file 4 | ## 5 | 6 | ## Name of project (so file is not empty) 7 | const package_name: String = "test" 8 | -------------------------------------------------------------------------------- /gdsbin/token.gd: -------------------------------------------------------------------------------- 1 | class_name Token 2 | 3 | ## GDScript Transpiler Properties Class 4 | ## 5 | ## Properties for Transpiler 6 | ## 7 | var id: int = 0 8 | var value: String = "" 9 | -------------------------------------------------------------------------------- /gdsbin/test/lambda_capture_callable.gd: -------------------------------------------------------------------------------- 1 | class_name Lambda_capture_callable 2 | 3 | func test(): 4 | var x = 42 5 | var my_lambda = func(): print(x) 6 | my_lambda.call() # Prints "42". 7 | -------------------------------------------------------------------------------- /gdsbin/test/operator_assign.gd: -------------------------------------------------------------------------------- 1 | class_name Operator_assign 2 | 3 | func test(): 4 | var i = 0 5 | i += 5 6 | i -= 4 7 | i *= 10 8 | i %= 8 9 | i /= 0.25 10 | print(round(i)) 11 | -------------------------------------------------------------------------------- /gdsbin/root.gd: -------------------------------------------------------------------------------- 1 | class_name Root 2 | ## GDScript Transpiler Properties Class 3 | ## 4 | ## Properties for Transpiler 5 | ## 6 | 7 | ## Method to process input string and list of tokens 8 | var elem: Array = [] 9 | -------------------------------------------------------------------------------- /docker/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sed '' update/run.sh > update/.run.sh 3 | chmod +x update/.run.sh 4 | docker build update -t codeberg.org/linuxusergd/gdsbin-amd64-musl-llvm:latest --progress=plain 5 | rm update/.run.sh 6 | -------------------------------------------------------------------------------- /gdsbin/version.gd: -------------------------------------------------------------------------------- 1 | class_name Version 2 | 3 | ## GDScript Version Script 4 | ## 5 | ## Script for printing version info 6 | ## 7 | ## 8 | 9 | 10 | ## Version info 11 | const __version__: String = "0.1.7" 12 | -------------------------------------------------------------------------------- /gdsbin/test/multiline_arrays.gd: -------------------------------------------------------------------------------- 1 | class_name Multiline_arrays 2 | 3 | func test(): 4 | var __ = [ 5 | "this", 6 | "is", "a","multiline", 7 | 8 | "array", "with mixed indentation and trailing comma", 9 | ] 10 | -------------------------------------------------------------------------------- /gdsbin/test/typed_arrays.gd: -------------------------------------------------------------------------------- 1 | class_name Typed_arrays 2 | 3 | func test(): 4 | var my_array: Array[int] = [1, 2, 3] 5 | var inferred_array := [1, 2, 3] # This is Array[int]. 6 | print(my_array) 7 | print(inferred_array) 8 | -------------------------------------------------------------------------------- /gdsbin/ifcond.gd: -------------------------------------------------------------------------------- 1 | class_name Ifcond 2 | ## GDScript Transpiler Properties Class 3 | ## 4 | ## Properties for Transpiler 5 | ## 6 | 7 | ## Method to process input string and list of tokens 8 | 9 | var i 10 | var root 11 | -------------------------------------------------------------------------------- /gdsbin/classn.gd: -------------------------------------------------------------------------------- 1 | class_name Classn 2 | ## GDScript Transpiler Properties Class 3 | ## 4 | ## Properties for Transpiler 5 | ## 6 | 7 | ## Method to process input string and list of tokens 8 | 9 | var classn: String = "" 10 | -------------------------------------------------------------------------------- /gdsbin/comment.gd: -------------------------------------------------------------------------------- 1 | class_name Comment 2 | ## GDScript Transpiler Properties Class 3 | ## 4 | ## Properties for Transpiler 5 | ## 6 | 7 | ## Method to process input string and list of tokens 8 | 9 | var comment: String = "" 10 | -------------------------------------------------------------------------------- /gdsbin/extend.gd: -------------------------------------------------------------------------------- 1 | class_name Extend 2 | ## GDScript Transpiler Properties Class 3 | ## 4 | ## Properties for Transpiler 5 | ## 6 | 7 | ## Method to process input string and list of tokens 8 | 9 | var extend: String = "" 10 | -------------------------------------------------------------------------------- /gdsbin/forloop.gd: -------------------------------------------------------------------------------- 1 | class_name Forloop 2 | ## GDScript Transpiler Properties Class 3 | ## 4 | ## Properties for Transpiler 5 | ## 6 | 7 | ## Method to process input string and list of tokens 8 | 9 | var f 10 | var i 11 | var root 12 | -------------------------------------------------------------------------------- /gdsbin/stringname.gd: -------------------------------------------------------------------------------- 1 | class_name Stringname 2 | ## GDScript Transpiler Properties Class 3 | ## 4 | ## Properties for Transpiler 5 | ## 6 | 7 | ## Method to process input string and list of tokens 8 | 9 | var string: String = "" 10 | -------------------------------------------------------------------------------- /gdsbin/test/if_after_lambda.gd: -------------------------------------------------------------------------------- 1 | class_name If_after_lambda 2 | 3 | # https://github.com/godotengine/godot/issues/61231 4 | 5 | func test(): 6 | var my_lambda = func(): 7 | print("hello") 8 | if 0 == 0: 9 | my_lambda.call() 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | 3 | contact_links: 4 | - name: Open a Issue 5 | url: https://codeberg.org/LinuxUserGD/gdscript-transpiler-bin/issues/new 6 | about: Open a new issue on codeberg.org. -------------------------------------------------------------------------------- /gdsbin/dictionaryname.gd: -------------------------------------------------------------------------------- 1 | class_name Dictionaryname 2 | ## GDScript Transpiler Properties Class 3 | ## 4 | ## Properties for Transpiler 5 | ## 6 | 7 | ## Method to process input string and list of tokens 8 | 9 | var items: Array = [] 10 | -------------------------------------------------------------------------------- /gdsbin/test/match_multiple_variable_binds_in_pattern.gd: -------------------------------------------------------------------------------- 1 | class_name Match_multiple_variable_binds_in_pattern 2 | 3 | func test(): 4 | match [1, 2, 3]: 5 | [var a, var b, var c]: 6 | print(a == 1) 7 | print(b == 2) 8 | print(c == 3) 9 | -------------------------------------------------------------------------------- /gdsbin/test/semicolon_as_end_statement.gd: -------------------------------------------------------------------------------- 1 | class_name Semicolon_as_end_statement 2 | 3 | func test(): 4 | print("A"); print("B") 5 | 6 | # Multiple semicolons and whitespace between them is also valid. 7 | print("A"); ;;;;; ; print("B");; 8 | -------------------------------------------------------------------------------- /docker/init/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gentoo/stage3:amd64-musl-llvm AS build 2 | 3 | WORKDIR / 4 | 5 | COPY .run.sh / 6 | ARG portage_upgrade=false 7 | RUN exec /.run.sh 8 | 9 | FROM scratch 10 | COPY --from=build / / 11 | 12 | CMD ["/bin/bash"] 13 | -------------------------------------------------------------------------------- /gdsbin/test/function_default_parameter_type_inference.gd: -------------------------------------------------------------------------------- 1 | class_name Function_default_parameter_type_inference 2 | 3 | func example(_number: int, _number2: int = 5, number3 := 10): 4 | return number3 5 | 6 | func test(): 7 | print(example(3)) 8 | -------------------------------------------------------------------------------- /gdsbin/test/nested_array.gd: -------------------------------------------------------------------------------- 1 | class_name Nested_array 2 | 3 | func test(): 4 | var array = [[[[[[[[[[15]]]]]]]]]] 5 | print(array[0][0][0][0][0][0][0][0]) 6 | print(array[0][0][0][0][0][0][0][0][0]) 7 | print(array[0][0][0][0][0][0][0][0][0][0]) 8 | -------------------------------------------------------------------------------- /gdsbin/test/enums.gd: -------------------------------------------------------------------------------- 1 | class_name Enums 2 | 3 | enum Size { 4 | S = -10, 5 | M, 6 | L = 0, 7 | XL = 10, 8 | XXL, 9 | } 10 | 11 | func test(): 12 | print(Size.S) 13 | print(Size.M) 14 | print(Size.L) 15 | print(Size.XL) 16 | print(Size.XXL) 17 | -------------------------------------------------------------------------------- /gdsbin/test/str_preserves_case.gd: -------------------------------------------------------------------------------- 1 | class_name Str_preserves_case 2 | 3 | func test(): 4 | var null_var = null 5 | var true_var: bool = true 6 | var false_var: bool = false 7 | print(str(null_var)) 8 | print(str(true_var)) 9 | print(str(false_var)) 10 | -------------------------------------------------------------------------------- /gdsbin/test/nested_function_calls.gd: -------------------------------------------------------------------------------- 1 | class_name Nested_function_calls 2 | 3 | func foo(x): 4 | return x + 1 5 | 6 | func test(): 7 | print(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(foo(0))))))))))))))))))))))))) 8 | -------------------------------------------------------------------------------- /gdsbin/test/trailing_comma_in_function_args.gd: -------------------------------------------------------------------------------- 1 | class_name Trailing_comma_in_function_args 2 | 3 | # See https://github.com/godotengine/godot/issues/41066. 4 | 5 | func f(p, ): ## <-- no errors 6 | print(p) 7 | 8 | func test(): 9 | f(0, ) ## <-- no error 10 | -------------------------------------------------------------------------------- /docker/update/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM codeberg.org/linuxusergd/gdsbin-amd64-musl-llvm:latest AS build 2 | 3 | WORKDIR / 4 | 5 | COPY .run.sh / 6 | ARG portage_upgrade=true 7 | RUN exec /.run.sh 8 | 9 | FROM scratch 10 | COPY --from=build / / 11 | 12 | CMD ["/bin/bash"] 13 | -------------------------------------------------------------------------------- /gdsbin/test/lambda_default_parameter_capture.gd: -------------------------------------------------------------------------------- 1 | class_name Lambda_default_parameter_capture 2 | 3 | # https://github.com/godotengine/godot/issues/56751 4 | 5 | func test(): 6 | var x = "local" 7 | var lambda = func(param = x): 8 | print(param) 9 | lambda.call() 10 | -------------------------------------------------------------------------------- /docker/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | pushd gentoo-docker-images > /dev/null 3 | TARGET=stage3-amd64-musl-llvm ./build.sh 4 | popd > /dev/null 5 | sed '' init/run.sh > init/.run.sh 6 | chmod +x init/.run.sh 7 | docker build init -t codeberg.org/linuxusergd/gdsbin-amd64-musl-llvm:latest --progress=plain 8 | rm init/.run.sh 9 | -------------------------------------------------------------------------------- /gdsbin/test/multiline_vector.gd: -------------------------------------------------------------------------------- 1 | class_name Multiline_vector 2 | 3 | func test(): 4 | Vector2( 5 | 1, 6 | 2 7 | ) 8 | 9 | Vector3( 10 | 3, 11 | 3.5, 12 | 4, # Trailing comma should work. 13 | ) 14 | 15 | Vector2i(1, 2,) # Trailing comma should work. 16 | 17 | Vector3i(6, 18 | 9, 19 | 12) 20 | -------------------------------------------------------------------------------- /gdsbin/function.gd: -------------------------------------------------------------------------------- 1 | class_name Function 2 | ## GDScript Transpiler Properties Class 3 | ## 4 | ## Properties for Transpiler 5 | ## 6 | 7 | ## Method to process input string and list of tokens 8 | 9 | var function: String = "" 10 | var args: Array = [] 11 | var res: String = "" 12 | var ret: bool = false 13 | var root 14 | -------------------------------------------------------------------------------- /gdsbin/test/multiline_dictionaries.gd: -------------------------------------------------------------------------------- 1 | class_name Multiline_dictionaries 2 | 3 | func test(): 4 | var __ = { 5 | "multiline": "dictionary","should": "work", 6 | "even with": "a trailing comma", 7 | } 8 | 9 | __ = { 10 | this_also_applies = "to the", 11 | lua_style_syntax = null, foo = null, 12 | } 13 | -------------------------------------------------------------------------------- /gdsbin/test/dictionary_lua_style.gd: -------------------------------------------------------------------------------- 1 | class_name Dictionary_lua_style 2 | 3 | func test(): 4 | var lua_dict = { 5 | a = 1, 6 | "b" = 2, # Using strings are allowed too. 7 | "with spaces" = 3, # Especially useful when key has spaces... 8 | "2" = 4, # ... or invalid identifiers. 9 | } 10 | 11 | print(lua_dict) 12 | -------------------------------------------------------------------------------- /gdsbin/test/multiline_if.gd: -------------------------------------------------------------------------------- 1 | class_name Multiline_if 2 | 3 | func test(): 4 | # Line breaks are allowed within parentheses. 5 | if ( 6 | 1 == 1 7 | and 2 == 2 and 8 | 3 == 3 9 | ): 10 | pass 11 | 12 | # Alternatively, backslashes can be used. 13 | if 1 == 1 \ 14 | and 2 == 2 and \ 15 | 3 == 3: 16 | pass 17 | -------------------------------------------------------------------------------- /gdsbin/test/dictionary_mixed_syntax.gd: -------------------------------------------------------------------------------- 1 | class_name Dictionary_mixed_syntax 2 | 3 | func test(): 4 | # Mixing Python-style and Lua-style syntax in the same dictionary declaration 5 | # is allowed. 6 | var dict = { 7 | "hello": { 8 | world = { 9 | "is": "beautiful", 10 | }, 11 | }, 12 | } 13 | 14 | print(dict) 15 | -------------------------------------------------------------------------------- /gdsbin/test/lambda_named_callable.gd: -------------------------------------------------------------------------------- 1 | class_name Lambda_named_callable 2 | 3 | func i_take_lambda(lambda: Callable, param: String): 4 | lambda.call(param) 5 | 6 | 7 | func test(): 8 | var my_lambda := func this_is_lambda(x): 9 | print("Hello") 10 | print("This is %s" % x) 11 | 12 | i_take_lambda(my_lambda, "a lambda") 13 | -------------------------------------------------------------------------------- /bin/gds.gd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/godot -s 2 | class_name GDScriptTranspiler 3 | extends SceneTree 4 | 5 | ## GDScript Wrapper 6 | ## 7 | ## Wrapper script for __main__.gd 8 | 9 | 10 | ## Run main application 11 | func _init() -> void: 12 | var gdsbin: Dictionary = {} 13 | gdsbin.__main__ = __Main__.new() 14 | gdsbin.__main__._ready() 15 | quit() 16 | -------------------------------------------------------------------------------- /bin/gds.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://bye4pq0ccnb0g"] 2 | 3 | [sub_resource type="GDScript" id="GDScript_dh7ia"] 4 | resource_name = "gds-node.gd" 5 | script/source = "extends Node 6 | 7 | func _ready(): 8 | GDScriptTranspiler.new() 9 | " 10 | 11 | [node name="gds" type="Node"] 12 | script = SubResource("GDScript_dh7ia") 13 | -------------------------------------------------------------------------------- /gdsbin/test/nested_dictionary.gd: -------------------------------------------------------------------------------- 1 | class_name Nested_dictionary 2 | 3 | func test(): 4 | var dictionary = {1: {2: {3: {4: {5: {6: {7: {8: {"key": "value"}}}}}}}}} 5 | print(dictionary[1][2][3][4][5][6][7]) 6 | print(dictionary[1][2][3][4][5][6][7][8]) 7 | print(dictionary[1][2][3][4][5][6][7][8].key) 8 | print(dictionary[1][2][3][4][5][6][7][8]["key"]) 9 | -------------------------------------------------------------------------------- /gdsbin/test/signal_declaration.gd: -------------------------------------------------------------------------------- 1 | class_name Signal_declaration 2 | 3 | #GDTEST_OK 4 | 5 | # No parentheses. 6 | signal a 7 | 8 | # No parameters. 9 | signal b() 10 | 11 | # With parameters. 12 | signal c(a, b, c) 13 | 14 | # With parameters multiline. 15 | signal d( 16 | a, 17 | b, 18 | c, 19 | ) 20 | 21 | func test(): 22 | print("Ok") 23 | -------------------------------------------------------------------------------- /gdsbin/variable.gd: -------------------------------------------------------------------------------- 1 | class_name Variable 2 | ## GDScript Transpiler Properties Class 3 | ## 4 | ## Properties for Transpiler 5 | ## 6 | 7 | ## Method to process input string and list of tokens 8 | var variable: String = "" 9 | var res 10 | var type: String = "" 11 | var st: bool = false 12 | var equ: bool = false 13 | var is_const: bool = false 14 | -------------------------------------------------------------------------------- /gdsbin/test/constants.gd: -------------------------------------------------------------------------------- 1 | class_name Constants 2 | 3 | func test(): 4 | const _TEST = 12 + 34 - 56 * 78 5 | const _STRING = "yes" 6 | const _VECTOR = Vector2(5, 6) 7 | const _ARRAY = [] 8 | const _DICTIONARY = {"this": "dictionary"} 9 | 10 | # Create user constants from built-in constants. 11 | const _HELLO = PI + TAU 12 | const _INFINITY = INF 13 | const _NOT_A_NUMBER = NAN 14 | -------------------------------------------------------------------------------- /gdsbin/callnew.gd: -------------------------------------------------------------------------------- 1 | class_name Callnew 2 | ## GDScript Transpiler Properties Class 3 | ## 4 | ## Properties for Transpiler 5 | ## 6 | 7 | ## Method to process input string and list of tokens 8 | 9 | var equ: bool = false 10 | var res 11 | var name: String = "" 12 | var function: bool = false 13 | var op: String = "" 14 | var args: Array = [] 15 | var builtin_function: bool = false 16 | var callnew: Callnew 17 | -------------------------------------------------------------------------------- /gdsbin/test/semicolon_as_terminator.gd: -------------------------------------------------------------------------------- 1 | class_name Semicolon_as_terminator 2 | 3 | #GDTEST_OK 4 | 5 | func test(): 6 | a(); 7 | b(); 8 | c(); 9 | d(); 10 | e(); 11 | 12 | func a(): print("a"); 13 | 14 | func b(): print("b1"); print("b2") 15 | 16 | func c(): print("c1"); print("c2"); 17 | 18 | func d(): 19 | print("d1"); 20 | print("d2") 21 | 22 | func e(): 23 | print("e1"); 24 | print("e2"); 25 | -------------------------------------------------------------------------------- /gdsbin/keyword.gd: -------------------------------------------------------------------------------- 1 | ## GDScript Transpiler Properties Class 2 | 3 | class_name Keyword 4 | 5 | const KW_NONE: int = 0 6 | const KW_CLASSNAME: int = -1 7 | const KW_EXTENDS: int = -2 8 | const KW_NUMBERSIGN2: int = -3 9 | const KW_FUNCTION: int = -4 10 | const KW_NEW: int = -5 11 | const KW_VARIABLE: int = -6 12 | const KW_CONST: int = -7 13 | const KW_FOR: int = -8 14 | const KW_IN: int = -9 15 | const KW_IF: int = -10 16 | -------------------------------------------------------------------------------- /gdsbin/test/match_bind_unused.gd: -------------------------------------------------------------------------------- 1 | class_name Match_bind_unused 2 | 3 | # https://github.com/godotengine/godot/pull/61666 4 | 5 | func test(): 6 | var dict := {"key": "value"} 7 | match dict: 8 | {"key": var value}: 9 | print(value) # used, no warning 10 | match dict: 11 | {"key": var value}: 12 | pass # unused, warning 13 | match dict: 14 | {"key": var _value}: 15 | pass # unused, suppressed warning from underscore 16 | -------------------------------------------------------------------------------- /gdsbin/test/matches.gd: -------------------------------------------------------------------------------- 1 | class_name Matches 2 | 3 | func test(): 4 | var i = "Hello" 5 | match i: 6 | "Hello": 7 | print("hello") 8 | # This will fall through to the default case below. 9 | # TODO: not working in python yet 10 | #continue 11 | "Good bye": 12 | print("bye") 13 | _: 14 | print("default") 15 | 16 | var j = 25 17 | match j: 18 | 26: 19 | print("This won't match") 20 | _: 21 | print("This will match") 22 | -------------------------------------------------------------------------------- /gdsbin/test/ins.gd: -------------------------------------------------------------------------------- 1 | class_name Ins 2 | 3 | func test(): 4 | print("dot" in "Godot") 5 | print(not "i" in "team") 6 | 7 | print(true in [true, false]) 8 | print(not null in [true, false]) 9 | print(null in [null]) 10 | 11 | print(26 in [8, 26, 64, 100]) 12 | print(not Vector2i(10, 20) in [Vector2i(20, 10)]) 13 | 14 | print("apple" in { "apple": "fruit" }) 15 | print("apple" in { "apple": null }) 16 | print(not "apple" in { "fruit": "apple" }) 17 | -------------------------------------------------------------------------------- /gdsbin/test/export_variable.gd: -------------------------------------------------------------------------------- 1 | class_name Export_variable 2 | 3 | @export var example = 99 4 | @export_range(0, 100) var example_range = 100 5 | @export_range(0, 100, 1) var example_range_step = 101 6 | @export_range(0, 100, 1, "or_greater") var example_range_step_or_greater = 102 7 | @export var color: Color 8 | 9 | 10 | func test(): 11 | print(example) 12 | print(example_range) 13 | print(example_range_step) 14 | print(example_range_step_or_greater) 15 | print(color) 16 | -------------------------------------------------------------------------------- /gdsbin/test/arrays.gd: -------------------------------------------------------------------------------- 1 | class_name Arrays 2 | 3 | func test(): 4 | # Indexing from the beginning: 5 | print([1, 2, 3][0]) 6 | print([1, 2, 3][1]) 7 | print([1, 2, 3][2]) 8 | 9 | # Indexing from the end: 10 | print([1, 2, 3][-1]) 11 | print([1, 2, 3][-2]) 12 | print([1, 2, 3][-3]) 13 | 14 | # Float indices are currently allowed, but should probably be an error? 15 | print([1, 2, 3][0.4]) 16 | print([1, 2, 3][0.8]) 17 | print([1, 2, 3][1.0]) 18 | print([1, 2, 3][-1.0]) 19 | -------------------------------------------------------------------------------- /gdsbin/test/static_typing.gd: -------------------------------------------------------------------------------- 1 | class_name Static_typing 2 | 3 | func test(): 4 | # The following lines are equivalent: 5 | var _integer: int = 1 6 | var _integer2 : int = 1 7 | var _inferred := 1 8 | var _inferred2 : = 1 9 | 10 | # Type inference is automatic for constants. 11 | const _INTEGER = 1 12 | const _INTEGER_REDUNDANT_TYPED : int = 1 13 | const _INTEGER_REDUNDANT_TYPED2 : int = 1 14 | const _INTEGER_REDUNDANT_INFERRED := 1 15 | const _INTEGER_REDUNDANT_INFERRED2 : = 1 16 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "gdUnit4"] 2 | path = gdUnit4 3 | url = https://github.com/MikeSchulze/gdUnit4.git 4 | remote = origin 5 | branch = master 6 | update = rebase 7 | [submodule "zig-template"] 8 | path = zig-template 9 | url = https://codeberg.org/LinuxUserGD/zig-template.git 10 | remote = origin 11 | branch = dev 12 | update = rebase 13 | [submodule "docker/gentoo-docker-images"] 14 | path = docker/gentoo-docker-images 15 | url = https://github.com/gentoo/gentoo-docker-images.git 16 | -------------------------------------------------------------------------------- /gdsbin/run_button.gd: -------------------------------------------------------------------------------- 1 | # Copyright © 2019-2022 Hugo Locurcio and contributors - MIT License 2 | # See `LICENSE.md` included in the source distribution for details. 3 | extends Button 4 | 5 | 6 | # The shortcut has to be implemented manually, so that it can block input in the 7 | # text editor. Otherwise, a line break would be inserted and the shortcut 8 | # wouldn't be triggered. 9 | func _input(event: InputEvent) -> void: 10 | if event.is_action_pressed("run_script"): 11 | emit_signal("pressed") 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /gdsbin/test/match_multiple_patterns_with_array.gd: -------------------------------------------------------------------------------- 1 | class_name Match_multiple_patterns_with_array 2 | 3 | func foo(x): 4 | match x: 5 | 1, [2]: 6 | print('1, [2]') 7 | _: 8 | print('wildcard') 9 | 10 | func bar(x): 11 | match x: 12 | [1], [2], [3]: 13 | print('[1], [2], [3]') 14 | [4]: 15 | print('[4]') 16 | _: 17 | print('wildcard') 18 | 19 | func test(): 20 | foo(1) 21 | foo([2]) 22 | foo(2) 23 | bar([1]) 24 | bar([2]) 25 | bar([3]) 26 | bar([4]) 27 | bar([5]) 28 | 29 | -------------------------------------------------------------------------------- /gdsbin/test/number_separators.gd: -------------------------------------------------------------------------------- 1 | class_name Number_separators 2 | 3 | func test(): 4 | # `_` can be used as a separator for numbers in GDScript. 5 | # It can be placed anywhere in the number, except at the beginning. 6 | # Currently, GDScript in the `master` branch only allows using one separator 7 | # per number. 8 | # Results are assigned to variables to avoid warnings. 9 | var __ = 1_23 10 | __ = 123_ # Trailing number separators are OK. 11 | __ = 12_3 12 | __ = 123_456 13 | __ = 0x1234_5678 14 | __ = 0b1001_0101 15 | -------------------------------------------------------------------------------- /gdsbin/test/variable_declaration.gd: -------------------------------------------------------------------------------- 1 | class_name Variable_declaration 2 | 3 | var m1 # No init. 4 | var m2 = 22 # Init. 5 | var m3: String # No init, typed. 6 | var m4: String = "44" # Init, typed. 7 | 8 | 9 | func test(): 10 | var loc5 # No init, local. 11 | var loc6 = 66 # Init, local. 12 | var loc7: String # No init, typed. 13 | var loc8: String = "88" # Init, typed. 14 | 15 | m1 = 11 16 | m3 = "33" 17 | 18 | loc5 = 55 19 | loc7 = "77" 20 | 21 | prints(m1, m2, m3, m4, loc5, loc6, loc7, loc8) 22 | print("OK") 23 | -------------------------------------------------------------------------------- /gdsbin/test/basic_expression_matching.gd: -------------------------------------------------------------------------------- 1 | class_name Basic_expression_matching 2 | 3 | func foo(x): 4 | match x: 5 | 1: 6 | print("1") 7 | 2: 8 | print("2") 9 | [1, 2]: 10 | print("[1, 2]") 11 | 3 or 4: 12 | print("3 or 4") 13 | 4: 14 | print("4") 15 | {1 : 2, 2 : 3}: 16 | print("{1 : 2, 2 : 3}") 17 | _: 18 | print("wildcard") 19 | 20 | func test(): 21 | foo(0) 22 | foo(1) 23 | foo(2) 24 | foo([1, 2]) 25 | foo(3) 26 | foo(4) 27 | foo([4,4]) 28 | foo({1 : 2, 2 : 3}) 29 | foo({1 : 2, 4 : 3}) 30 | -------------------------------------------------------------------------------- /gdsbin/test/dollar_node_paths.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | class_name Dollar_node_paths 3 | 4 | func test(): 5 | # Create the required node structure. 6 | var hello = Node.new() 7 | hello.name = "Hello" 8 | add_child(hello) 9 | var world = Node.new() 10 | world.name = "World" 11 | hello.add_child(world) 12 | 13 | # All the ways of writing node paths below with the `$` operator are valid. 14 | # Results are assigned to variables to avoid warnings. 15 | var __ = $Hello 16 | __ = $"Hello" 17 | __ = $Hello/World 18 | __ = $"Hello/World" 19 | __ = $"Hello/.." 20 | __ = $"Hello/../Hello/World" 21 | -------------------------------------------------------------------------------- /icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gdsbin/main_window.gd: -------------------------------------------------------------------------------- 1 | # Copyright © 2019-2022 Hugo Locurcio and contributors - MIT License 2 | # See `LICENSE.md` included in the source distribution for details. 3 | extends Control 4 | 5 | @onready var engine_version_label := $EngineVersion as Label 6 | 7 | func _ready() -> void: 8 | var version: Dictionary = Engine.get_version_info() 9 | # Mimic the official version numbering. 10 | if version.patch >= 1: 11 | engine_version_label.text = "Godot %s.%s.%s.%s" % [version.major, version.minor, version.patch, version.status] 12 | else: 13 | engine_version_label.text = "Godot %s.%s.%s" % [version.major, version.minor, version.status] 14 | -------------------------------------------------------------------------------- /gdsbin/test/for_range.gd: -------------------------------------------------------------------------------- 1 | class_name For_range 2 | 3 | func test(): 4 | for i in range(5): 5 | print(i) 6 | 7 | print() 8 | 9 | # Equivalent to the above `for` loop: 10 | for i in 5: 11 | print(i) 12 | 13 | print() 14 | 15 | for i in range(1, 5): 16 | print(i) 17 | 18 | print() 19 | 20 | for i in range(1, -5, -1): 21 | print(i) 22 | 23 | print() 24 | 25 | for i in [2, 4, 6, -8]: 26 | print(i) 27 | 28 | print() 29 | 30 | for i in [true, false]: 31 | print(i) 32 | 33 | print() 34 | 35 | for i in [Vector2i(10, 20), Vector2i(-30, -40)]: 36 | print(i) 37 | 38 | print() 39 | 40 | for i in "Hello_Unicôde_world!_🦄": 41 | print(i) 42 | -------------------------------------------------------------------------------- /gdsbin/test/multiline_strings.gd: -------------------------------------------------------------------------------- 1 | class_name Multiline_strings 2 | 3 | func test(): 4 | var __ = """ 5 | This is a standalone string, not a multiline comment. 6 | Writing both "double" quotes and 'simple' quotes is fine as 7 | long as there is only ""one"" or ''two'' of those in a row, not more. 8 | 9 | If you have more quotes, they need to be escaped like this: \"\"\" 10 | """ 11 | __ = ''' 12 | Another standalone string, this time with single quotes. 13 | Writing both "double" quotes and 'simple' quotes is fine as 14 | long as there is only ""one"" or ''two'' of those in a row, not more. 15 | 16 | If you have more quotes, they need to be escaped like this: \'\'\' 17 | ''' 18 | -------------------------------------------------------------------------------- /.forgejo/ISSUE_TEMPLATE/request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]" 5 | ref: 'dev' 6 | labels: 7 | - enhancement 8 | 9 | --- 10 | 11 | **Is your feature request related to a problem? Please describe.** 12 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 13 | 14 | **Describe the solution you'd like** 15 | A clear and concise description of what you want to happen. 16 | 17 | **Describe alternatives you've considered** 18 | A clear and concise description of any alternative solutions or features you've considered. 19 | 20 | **Additional context** 21 | Add any other context or screenshots about the feature request here. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Godot-specific ignores 2 | export.cfg 3 | 4 | # Mono-specific ignores 5 | .mono/ 6 | data_*/ 7 | 8 | # Godot 4+ specific ignores 9 | .godot/* 10 | !.godot/global_script_class_cache.cfg 11 | export_presets.cfg 12 | extension_api.json 13 | 14 | # Python 15 | *.py 16 | *.pyc 17 | pyproject.toml 18 | 19 | # Nuitka 20 | *.bin 21 | 22 | # GitHub Workflows 23 | .github/ 24 | 25 | # Logs when editor logging is enabled 26 | logs/ 27 | 28 | # Exported files 29 | dist/ 30 | gdsbin/__pycache__/ 31 | bin/__pycache__/ 32 | gdsbin/test/__pycache__/ 33 | gds.egg-info/ 34 | gds.dist/ 35 | gds.onefile-build/ 36 | gds.build/ 37 | 38 | # Python Archive 39 | archive.tar.xz 40 | 41 | # Zig 42 | .zig-cache/ 43 | zig-out/ 44 | out/ 45 | 46 | docker/init/.run.sh 47 | docker/update/.run.sh 48 | -------------------------------------------------------------------------------- /gdsbin/test/string_formatting.gd: -------------------------------------------------------------------------------- 1 | class_name String_formatting 2 | 3 | func test(): 4 | print("hello %s" % "world" == "hello world") 5 | print("hello %s" % true == "hello true") 6 | print("hello %s" % false == "hello false") 7 | 8 | print("hello %d" % 25 == "hello 25") 9 | print("hello %d %d" % [25, 42] == "hello 25 42") 10 | # Pad with spaces. 11 | print("hello %3d" % 25 == "hello 25") 12 | # Pad with zeroes. 13 | print("hello %03d" % 25 == "hello 025") 14 | 15 | print("hello %.02f" % 0.123456 == "hello 0.12") 16 | 17 | # Dynamic padding: 18 | # 19 | print("hello %*.*f" % [7, 3, 0.123456] == "hello 0.123") 20 | print("hello %0*.*f" % [7, 3, 0.123456] == "hello 000.123") 21 | -------------------------------------------------------------------------------- /gdsbin/test/advanced_expression_matching.gd: -------------------------------------------------------------------------------- 1 | class_name Advanced_expression_matching 2 | 3 | func foo(x): 4 | match x: 5 | 1 + 1: 6 | print("1+1") 7 | [1,2,[1,{1:2,2:var z,..}]]: 8 | print("[1,2,[1,{1:2,2:var z,..}]]") 9 | print(z) 10 | 1 if true else 2: 11 | print("1 if true else 2") 12 | 1 < 2: 13 | print("1 < 2") 14 | 1 or 2 and 1: 15 | print("1 or 2 and 1") 16 | 6 | 1: 17 | print("1 | 1") 18 | 1 >> 1: 19 | print("1 >> 1") 20 | 1, 2 or 3, 4: 21 | print("1, 2 or 3, 4") 22 | _: 23 | print("wildcard") 24 | 25 | func test(): 26 | foo(6 | 1) 27 | foo(1 >> 1) 28 | foo(2) 29 | foo(1) 30 | foo(1+1) 31 | foo(1 < 2) 32 | foo([2, 1]) 33 | foo(4) 34 | foo([1, 2, [1, {1 : 2, 2:3}]]) 35 | foo([1, 2, [1, {1 : 2, 2:[1,3,5, "123"], 4:2}]]) 36 | foo([1, 2, [1, {1 : 2}]]) 37 | -------------------------------------------------------------------------------- /gdsbin/__init__.gd: -------------------------------------------------------------------------------- 1 | ## GDScript Init File 2 | ## 3 | 4 | const setuptools_min_ver: int = 42 5 | 6 | ## Name of project 7 | const package_name: String = "gdsbin" 8 | const author: String = "LinuxUserGD" 9 | const author_email: String = "hugegameartgd@gmail.com" 10 | const project_url: String = "https://codeberg.org/LinuxUserGD/gdscript-transpiler-bin" 11 | const download_url: String = "https://linuxusergd.itch.io/gdscript-transpiler-bin" 12 | const documentation_url: String = "https://codeberg.org/LinuxUserGD/gdscript-transpiler-bin/wiki" 13 | const source_url: String = "https://codeberg.org/LinuxUserGD/gdscript-transpiler-bin" 14 | const tracker_url: String = "https://codeberg.org/LinuxUserGD/gdscript-transpiler-bin/issues" 15 | const description: String = "GDScript and Python runtime environment" 16 | const proj_license: String = "MIT" 17 | -------------------------------------------------------------------------------- /gdsbin/fonts/hack_regular.ttf.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="font_data_dynamic" 4 | type="FontFile" 5 | uid="uid://bwt6t2q5kbjbe" 6 | path="res://.godot/imported/hack_regular.ttf-a1e988799fc302b0920dc6a71c3573dd.fontdata" 7 | 8 | [deps] 9 | 10 | source_file="res://gdsbin/fonts/hack_regular.ttf" 11 | dest_files=["res://.godot/imported/hack_regular.ttf-a1e988799fc302b0920dc6a71c3573dd.fontdata"] 12 | 13 | [params] 14 | 15 | Rendering=null 16 | antialiasing=1 17 | generate_mipmaps=false 18 | disable_embedded_bitmaps=true 19 | multichannel_signed_distance_field=false 20 | msdf_pixel_range=8 21 | msdf_size=48 22 | allow_system_fallback=true 23 | force_autohinter=false 24 | modulate_color_glyphs=false 25 | hinting=1 26 | subpixel_positioning=1 27 | keep_rounding_remainders=true 28 | oversampling=0.0 29 | Fallbacks=null 30 | fallbacks=[] 31 | Compress=null 32 | compress=true 33 | preload=[] 34 | language_support={} 35 | script_support={} 36 | opentype_features={} 37 | -------------------------------------------------------------------------------- /gdsbin/application.gd: -------------------------------------------------------------------------------- 1 | class_name Application 2 | 3 | ## GDScript Execute compatibility class 4 | ## 5 | ## GDScript Wrapper class for OS execute 6 | 7 | func execute(program: String, args: Array) -> Array: 8 | var stdout: Array = [] 9 | OS.execute(program,args,stdout) 10 | return stdout 11 | 12 | func execute_pipe(program: String, args: Array) -> void: 13 | var info: Dictionary = OS.execute_with_pipe(program,args) 14 | if info["stdio"]: 15 | _create_thread(info["stdio"]) 16 | 17 | func _create_thread(pipe: Object): 18 | var main: Callable = Callable(self, "_start_thread").bind(pipe) 19 | var thread: Thread = Thread.new() 20 | thread.start(main) 21 | thread.wait_to_finish() 22 | pipe.close() 23 | 24 | func _start_thread(pipe: Object) -> void: 25 | var line: String = "" 26 | while pipe.is_open() and pipe.get_error() == OK: 27 | var c: String = char(pipe.get_8()) 28 | if c == "\n": 29 | print(line) 30 | line = "" 31 | else: 32 | line += c 33 | -------------------------------------------------------------------------------- /gdsbin/fonts/noto_sans_regular.ttf.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="font_data_dynamic" 4 | type="FontFile" 5 | uid="uid://decvm47txmafw" 6 | path="res://.godot/imported/noto_sans_regular.ttf-c4213928bf48e3871506815a466c3b12.fontdata" 7 | 8 | [deps] 9 | 10 | source_file="res://gdsbin/fonts/noto_sans_regular.ttf" 11 | dest_files=["res://.godot/imported/noto_sans_regular.ttf-c4213928bf48e3871506815a466c3b12.fontdata"] 12 | 13 | [params] 14 | 15 | Rendering=null 16 | antialiasing=1 17 | generate_mipmaps=false 18 | disable_embedded_bitmaps=true 19 | multichannel_signed_distance_field=false 20 | msdf_pixel_range=8 21 | msdf_size=48 22 | allow_system_fallback=true 23 | force_autohinter=false 24 | modulate_color_glyphs=false 25 | hinting=1 26 | subpixel_positioning=1 27 | keep_rounding_remainders=true 28 | oversampling=0.0 29 | Fallbacks=null 30 | fallbacks=[] 31 | Compress=null 32 | compress=true 33 | preload=[] 34 | language_support={} 35 | script_support={} 36 | opentype_features={} 37 | -------------------------------------------------------------------------------- /gdsbin/test/property_setter_getter.gd: -------------------------------------------------------------------------------- 1 | class_name Property_setter_getter 2 | 3 | # 4.0+ replacement for `setget`: 4 | var _backing: int = 0 5 | var property: 6 | get: 7 | return _backing + 1000 8 | set(value): 9 | _backing = value - 1000 10 | 11 | 12 | func test(): 13 | print("Not using self:") 14 | print(property) 15 | print(_backing) 16 | property = 5000 17 | print(property) 18 | print(_backing) 19 | _backing = -50 20 | print(property) 21 | print(_backing) 22 | property = 5000 23 | print(property) 24 | print(_backing) 25 | 26 | # In Godot 4.0 and later, using `self` no longer makes a difference for 27 | # getter/setter execution in GDScript. 28 | print("Using self:") 29 | print(self.property) 30 | print(self._backing) 31 | self.property = 5000 32 | print(self.property) 33 | print(self._backing) 34 | self._backing = -50 35 | print(self.property) 36 | print(self._backing) 37 | self.property = 5000 38 | print(self.property) 39 | print(self._backing) 40 | -------------------------------------------------------------------------------- /mit.svg: -------------------------------------------------------------------------------- 1 | LicenseMIT -------------------------------------------------------------------------------- /gdsbin/test/function_many_parameters.gd: -------------------------------------------------------------------------------- 1 | class_name Function_many_parameters 2 | 3 | func example(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, arg26, arg27, arg28, arg29, arg30, arg31, arg32, arg33, arg34, arg35, arg36, arg37, arg38, arg39, arg40, arg41, arg42, arg43, arg44, arg45, arg46, arg47, arg48 = false, arg49 = true, arg50 = null): 4 | print(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, arg26, arg27, arg28, arg29, arg30, arg31, arg32, arg33, arg34, arg35, arg36, arg37, arg38, arg39, arg40, arg41, arg42, arg43, arg44, arg45, arg46, arg47, arg48, arg49, arg50) 5 | 6 | func test(): 7 | example(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 2, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47) 8 | -------------------------------------------------------------------------------- /python.svg: -------------------------------------------------------------------------------- 1 | python2.7 | 3.3 – 3.13 2 | -------------------------------------------------------------------------------- /gdsbin/test/truthiness.gd: -------------------------------------------------------------------------------- 1 | class_name Truthiness 2 | 3 | func test(): 4 | # The assertions below should all evaluate to `true` for this test to pass. 5 | assert(true) 6 | assert(not false) 7 | assert(500) 8 | assert(not 0) 9 | assert(500.5) 10 | assert(not 0.0) 11 | assert("non-empty string") 12 | assert(["non-empty array"]) 13 | assert({"non-empty": "dictionary"}) 14 | assert(Vector2(1, 0)) 15 | assert(Vector2i(-1, -1)) 16 | assert(Vector3(0, 0, 0.0001)) 17 | assert(Vector3i(0, 0, 10000)) 18 | 19 | # Zero position is `true` only if the Rect2's size is non-zero. 20 | assert(Rect2(0, 0, 0, 1)) 21 | 22 | # Zero size is `true` only if the position is non-zero. 23 | assert(Rect2(1, 1, 0, 0)) 24 | 25 | # Zero position is `true` only if the Rect2's size is non-zero. 26 | assert(Rect2i(0, 0, 0, 1)) 27 | 28 | # Zero size is `true` only if the position is non-zero. 29 | assert(Rect2i(1, 1, 0, 0)) 30 | 31 | # A fully black color is only truthy if its alpha component is not equal to `1`. 32 | assert(Color(0, 0, 0, 0.5)) 33 | -------------------------------------------------------------------------------- /gdsbin/variant_operator.gd: -------------------------------------------------------------------------------- 1 | ## GDScript Transpiler Properties Class 2 | 3 | # Autogenerated class (gen_api) 4 | # See https://raw.githubusercontent.com/godotengine/godot-cpp/master/gdextension/extension_api.json 5 | 6 | class_name Variant_operator 7 | 8 | const OP_EQUAL: int = 0 9 | const OP_NOT_EQUAL: int = 1 10 | const OP_LESS: int = 2 11 | const OP_LESS_EQUAL: int = 3 12 | const OP_GREATER: int = 4 13 | const OP_GREATER_EQUAL: int = 5 14 | const OP_ADD: int = 6 15 | const OP_SUBTRACT: int = 7 16 | const OP_MULTIPLY: int = 8 17 | const OP_DIVIDE: int = 9 18 | const OP_NEGATE: int = 10 19 | const OP_POSITIVE: int = 11 20 | const OP_MODULE: int = 12 21 | const OP_POWER: int = 13 22 | const OP_SHIFT_LEFT: int = 14 23 | const OP_SHIFT_RIGHT: int = 15 24 | const OP_BIT_AND: int = 16 25 | const OP_BIT_OR: int = 17 26 | const OP_BIT_XOR: int = 18 27 | const OP_BIT_NEGATE: int = 19 28 | const OP_AND: int = 20 29 | const OP_OR: int = 21 30 | const OP_XOR: int = 22 31 | const OP_NOT: int = 23 32 | const OP_IN: int = 24 33 | const OP_MAX: int = 25 34 | -------------------------------------------------------------------------------- /gdsbin/test/float_notation.gd: -------------------------------------------------------------------------------- 1 | class_name Float_notation 2 | 3 | func test(): 4 | # The following floating-point notations are all valid: 5 | print(is_equal_approx(123., 123)) 6 | print(is_equal_approx(.123, 0.123)) 7 | print(is_equal_approx(.123e4, 1230)) 8 | print(is_equal_approx(123.e4, 1.23e6)) 9 | print(is_equal_approx(.123e-1, 0.0123)) 10 | print(is_equal_approx(123.e-1, 12.3)) 11 | 12 | # Same as above, but with negative numbers. 13 | print(is_equal_approx(-123., -123)) 14 | print(is_equal_approx(-.123, -0.123)) 15 | print(is_equal_approx(-.123e4, -1230)) 16 | print(is_equal_approx(-123.e4, -1.23e6)) 17 | print(is_equal_approx(-.123e-1, -0.0123)) 18 | print(is_equal_approx(-123.e-1, -12.3)) 19 | 20 | # Same as above, but with explicit positive numbers (which is redundant). 21 | print(is_equal_approx(+123., +123)) 22 | print(is_equal_approx(+.123, +0.123)) 23 | print(is_equal_approx(+.123e4, +1230)) 24 | print(is_equal_approx(+123.e4, +1.23e6)) 25 | print(is_equal_approx(+.123e-1, +0.0123)) 26 | print(is_equal_approx(+123.e-1, +12.3)) 27 | -------------------------------------------------------------------------------- /.forgejo/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | ref: 'dev' 6 | blank_issues_enabled: false 7 | milestone: '2164' 8 | labels: 9 | - bug 10 | 11 | --- 12 | 13 | **Describe the bug** 14 | A clear and concise description of what the bug is. 15 | 16 | **To Reproduce** 17 | Steps to reproduce the behavior: 18 | 1. Go to '...' 19 | 2. Click on '....' 20 | 3. Scroll down to '....' 21 | 4. See error 22 | 23 | **Expected behavior** 24 | A clear and concise description of what you expected to happen. 25 | 26 | **Screenshots** 27 | If applicable, add screenshots to help explain your problem. 28 | 29 | **Desktop (please complete the following information):** 30 | - OS: [e.g. iOS] 31 | - Browser [e.g. chrome, safari] 32 | - Version [e.g. 22] 33 | 34 | **Smartphone (please complete the following information):** 35 | - Device: [e.g. iPhone6] 36 | - OS: [e.g. iOS8.1] 37 | - Browser [e.g. stock browser, safari] 38 | - Version [e.g. 22] 39 | 40 | **Additional context** 41 | Add any other context about the problem here. -------------------------------------------------------------------------------- /gdsbin/test/bitwise_operators.gd: -------------------------------------------------------------------------------- 1 | class_name Bitwise_operators 2 | 3 | enum Flags { 4 | FIRE = 1 << 1, 5 | ICE = 1 << 2, 6 | SLIPPERY = 1 << 3, 7 | STICKY = 1 << 4, 8 | NONSOLID = 1 << 5, 9 | 10 | ALL = FIRE | ICE | SLIPPERY | STICKY | NONSOLID, 11 | } 12 | 13 | 14 | func test(): 15 | var flags = Flags.FIRE | Flags.SLIPPERY 16 | print(flags) 17 | 18 | flags = Flags.FIRE & Flags.SLIPPERY 19 | print(flags) 20 | 21 | flags = Flags.FIRE ^ Flags.SLIPPERY 22 | print(flags) 23 | 24 | flags = Flags.ALL & (Flags.FIRE | Flags.ICE) 25 | print(flags) 26 | 27 | flags = (Flags.ALL & Flags.FIRE) | Flags.ICE 28 | print(flags) 29 | 30 | flags = Flags.ALL & Flags.FIRE | Flags.ICE 31 | print(flags) 32 | 33 | # Enum value must be casted to an integer. Otherwise, a parser error is emitted. 34 | flags &= int(Flags.ICE) 35 | print(flags) 36 | 37 | flags ^= int(Flags.ICE) 38 | print(flags) 39 | 40 | flags |= int(Flags.STICKY | Flags.SLIPPERY) 41 | print(flags) 42 | 43 | print() 44 | 45 | var num = 2 << 4 46 | print(num) 47 | 48 | num <<= 2 49 | print(num) 50 | 51 | num >>= 2 52 | print(num) 53 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 LinuxUserGD and contributors 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. 22 | -------------------------------------------------------------------------------- /gdsbin/test/nested_arithmetic.gd: -------------------------------------------------------------------------------- 1 | class_name Nested_arithmetic 2 | 3 | func test(): 4 | print(+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++2.718) 5 | 6 | print() 7 | 8 | print(------------------------------------------------------------------2.718) 9 | print(-------------------------------------------------------------------2.718) 10 | 11 | print() 12 | 13 | print(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~999) 14 | 15 | print() 16 | 17 | print(+-+-+-----+------------+++++++---++--++--+--+---+--++2.718) 18 | 19 | print() 20 | 21 | print(2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 / 2 / 2 / 2 / 2 / 2 / 2 / 2 / 2 / 2 / 2 / 2 / 2 / 2 / 2 / 2 / 2 / 2 / 0.444) 22 | print(153023902390239 % 550 % 29 % 27 % 23 % 17) 23 | print(2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2 >> 2) 24 | print(8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8 ^ -8 ^ 8 ^ 8 ^ 8 ^ 8 ^ 8) 25 | -------------------------------------------------------------------------------- /gdsbin/test/match_dictionary.gd: -------------------------------------------------------------------------------- 1 | class_name Match_dictionary 2 | 3 | func foo(x): 4 | match x: 5 | {"key1": "value1", "key2": "value2"}: 6 | print('{"key1": "value1", "key2": "value2"}') 7 | {"key1": "value1", "key2"}: 8 | print('{"key1": "value1", "key2"}') 9 | {"key1", "key2": "value2"}: 10 | print('{"key1", "key2": "value2"}') 11 | {"key1", "key2"}: 12 | print('{"key1", "key2"}') 13 | {"key1": "value1"}: 14 | print('{"key1": "value1"}') 15 | {"key1"}: 16 | print('{"key1"}') 17 | _: 18 | print("wildcard") 19 | 20 | func bar(x): 21 | match x: 22 | {0}: 23 | print("0") 24 | {1}: 25 | print("1") 26 | {2}: 27 | print("2") 28 | _: 29 | print("wildcard") 30 | 31 | func test(): 32 | foo({"key1": "value1", "key2": "value2"}) 33 | foo({"key1": "value1", "key2": ""}) 34 | foo({"key1": "", "key2": "value2"}) 35 | foo({"key1": "", "key2": ""}) 36 | foo({"key1": "value1"}) 37 | foo({"key1": ""}) 38 | foo({"key1": "value1", "key2": "value2", "key3": "value3"}) 39 | foo({"key1": "value1", "key3": ""}) 40 | foo({"key2": "value2"}) 41 | foo({"key3": ""}) 42 | bar({0: "0"}) 43 | bar({1: "1"}) 44 | bar({2: "2"}) 45 | bar({3: "3"}) 46 | -------------------------------------------------------------------------------- /gdsbin/test/dictionaries.gd: -------------------------------------------------------------------------------- 1 | class_name Dictionaries 2 | 3 | func test(): 4 | # Non-string keys are valid. 5 | print({ 12: "world" }[12]) 6 | 7 | var contents = { 8 | 0: "zero", 9 | 0.0: "zero point zero", 10 | null: "null", 11 | false: "false", 12 | []: "empty array", 13 | Vector2i(): "zero Vector2i", 14 | 15: { 15 | 22: { 16 | 4: ["nesting", "arrays"], 17 | }, 18 | }, 19 | } 20 | 21 | print(contents[0.0]) 22 | # Making sure declaration order doesn't affect things... 23 | print({ 0.0: "zero point zero", 0: "zero", null: "null", false: "false", []: "empty array" }[0]) 24 | print({ 0.0: "zero point zero", 0: "zero", null: "null", false: "false", []: "empty array" }[0.0]) 25 | 26 | print(contents[null]) 27 | print(contents[false]) 28 | print(contents[[]]) 29 | print(contents[Vector2i()]) 30 | print(contents[15]) 31 | print(contents[15][22]) 32 | print(contents[15][22][4]) 33 | print(contents[15][22][4][0]) 34 | print(contents[15][22][4][1]) 35 | 36 | # Currently fails with "invalid get index 'hello' on base Dictionary". 37 | # Both syntaxes are valid however. 38 | #print({ "hello": "world" }["hello"]) 39 | #print({ "hello": "world" }.hello) 40 | -------------------------------------------------------------------------------- /icon.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://7ni6b5l5pf3v" 6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.svg" 14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /mit.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://ctsponj52hxkq" 6 | path="res://.godot/imported/mit.svg-ad12482d6f32c2c4497e5a330b5e5f23.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://mit.svg" 14 | dest_files=["res://.godot/imported/mit.svg-ad12482d6f32c2c4497e5a330b5e5f23.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /python.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bt47ee7jfdx5g" 6 | path="res://.godot/imported/python.svg-d6262c1b34c685fcfee8cedc75f9d1cf.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://python.svg" 14 | dest_files=["res://.godot/imported/python.svg-d6262c1b34c685fcfee8cedc75f9d1cf.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /Godot-v.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dattmr3bxsk22" 6 | path="res://.godot/imported/Godot-v.svg-ac2e6e8123fb2ea528ce20c541c69b8b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Godot-v.svg" 14 | dest_files=["res://.godot/imported/Godot-v.svg-ac2e6e8123fb2ea528ce20c541c69b8b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /gdsbin/file.gd: -------------------------------------------------------------------------------- 1 | class_name File 2 | 3 | ## GDScript File compatibility class 4 | ## 5 | ## GDScript Wrapper class for previous File options 6 | ## (which were changed to static FileAccess) 7 | 8 | 9 | ## Internal File variable (using FileAccess) 10 | var file: FileAccess 11 | var path: String = "" 12 | 13 | ## FileOpts enum options for different FileAccess types 14 | enum FileOpts {READ, WRITE, WRITE_READ, READ_WRITE} 15 | 16 | ## "Open" function for compatibility 17 | func open(path_str : String, fo : FileOpts) -> void: 18 | self.path = path_str 19 | var opts 20 | match fo: 21 | FileOpts.READ: 22 | opts = FileAccess.READ 23 | FileOpts.WRITE: 24 | opts = FileAccess.WRITE 25 | FileOpts.WRITE_READ: 26 | opts = FileAccess.WRITE_READ 27 | FileOpts.READ_WRITE: 28 | opts = FileAccess.READ_WRITE 29 | self.file = FileAccess.open(self.path, opts) 30 | 31 | ## "Get as text" function for compatibility 32 | func get_as_text() -> String: 33 | if self.file != null: 34 | return self.file.get_as_text() 35 | else: 36 | print("Error: File '" + self.path + "' does not exist") 37 | return "" 38 | 39 | ## "Store string" function for compatibility 40 | func store_string(string : String) -> void: 41 | self.file.store_string(string) 42 | 43 | ## "Close" function for compatibility 44 | func close() -> void: 45 | file = null 46 | -------------------------------------------------------------------------------- /gdsbin/test/dollar_and_percent_get_node.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | class_name Dollar_and_percent_get_node 3 | 4 | func test(): 5 | var child = Node.new() 6 | child.name = "Child" 7 | add_child(child) 8 | child.owner = self 9 | 10 | var hey = Node.new() 11 | hey.name = "Hey" 12 | child.add_child(hey) 13 | hey.owner = self 14 | hey.unique_name_in_owner = true 15 | 16 | var fake_hey = Node.new() 17 | fake_hey.name = "Hey" 18 | add_child(fake_hey) 19 | fake_hey.owner = self 20 | 21 | var sub_child = Node.new() 22 | sub_child.name = "SubChild" 23 | hey.add_child(sub_child) 24 | sub_child.owner = self 25 | 26 | var howdy = Node.new() 27 | howdy.name = "Howdy" 28 | sub_child.add_child(howdy) 29 | howdy.owner = self 30 | howdy.unique_name_in_owner = true 31 | 32 | print(hey == $Child/Hey) 33 | print(howdy == $Child/Hey/SubChild/Howdy) 34 | 35 | print(%Hey == hey) 36 | print($%Hey == hey) 37 | print(%"Hey" == hey) 38 | print($"%Hey" == hey) 39 | print($%"Hey" == hey) 40 | print(%Hey/%Howdy == howdy) 41 | print($%Hey/%Howdy == howdy) 42 | print($"%Hey/%Howdy" == howdy) 43 | print($"%Hey"/"%Howdy" == howdy) 44 | print(%"Hey"/"%Howdy" == howdy) 45 | print($%"Hey"/"%Howdy" == howdy) 46 | print($"%Hey"/%"Howdy" == howdy) 47 | print(%"Hey"/%"Howdy" == howdy) 48 | print($%"Hey"/%"Howdy" == howdy) 49 | print(%"Hey/%Howdy" == howdy) 50 | print($%"Hey/%Howdy" == howdy) 51 | -------------------------------------------------------------------------------- /gdsbin/test/arrays_dictionaries_nested_const.gd: -------------------------------------------------------------------------------- 1 | class_name Arrays_dictionaries_nested_const 2 | 3 | # https://github.com/godotengine/godot/issues/50285 4 | 5 | func test(): 6 | const _CONST_INNER_DICTIONARY = { "key": true } 7 | const _CONST_NESTED_DICTIONARY_OLD_WORKAROUND = { 8 | "key1": "value1", 9 | "key2": _CONST_INNER_DICTIONARY 10 | } 11 | # All of these should be valid 12 | const _CONST_NESTED_DICTIONARY = { 13 | "key1": "value1", 14 | "key2": { "key": true } 15 | } 16 | 17 | 18 | const _CONST_DICTIONARY_WITH_ARRAY = { 19 | "key1": [1,2,3,4] 20 | } 21 | 22 | const _CONST_NESTED_ARRAY = [[],[2],[1,2,3]] 23 | const _CONST_ARRAY_WITH_DICT = [{"key1": 3}, {"key2": 5}] 24 | 25 | const _THREE_DIMENSIONAL_ARRAY = [[[],[],[]],[[],[],[]],[[],[],[]]] 26 | const _MANY_NESTED_DICT = { 27 | "key1": { 28 | "key11": { 29 | "key111": {}, 30 | "key112": {}, 31 | }, 32 | "key12": { 33 | "key121": {}, 34 | "key122": {}, 35 | }, 36 | }, 37 | "key2": { 38 | "key21": { 39 | "key211": {}, 40 | "key212": {}, 41 | }, 42 | "key22": { 43 | "key221": {}, 44 | "key222": {}, 45 | }, 46 | } 47 | } 48 | 49 | 50 | const CONST_ARRAY_ACCESS = [1,2,3][0] 51 | const CONST_DICT_ACCESS = {"key1": 5}["key1"] 52 | 53 | const CONST_ARRAY_NESTED_ACCESS = [[1,2,3],[4,5,6],[8,9,10]][0][1] 54 | const CONST_DICT_NESTED_ACCESS = {"key1": {"key2": 1}}["key1"]["key2"] 55 | 56 | print(CONST_ARRAY_ACCESS) 57 | print(CONST_DICT_ACCESS) 58 | print(CONST_ARRAY_NESTED_ACCESS) 59 | print(CONST_DICT_NESTED_ACCESS) 60 | -------------------------------------------------------------------------------- /gdsbin/variant_type.gd: -------------------------------------------------------------------------------- 1 | ## GDScript Transpiler Properties Class 2 | 3 | # Autogenerated class (gen_api) 4 | # See https://raw.githubusercontent.com/godotengine/godot-cpp/master/gdextension/extension_api.json 5 | 6 | class_name Variant_type 7 | 8 | const TYPE_NIL: int = 0 9 | const TYPE_BOOL: int = 1 10 | const TYPE_INT: int = 2 11 | const TYPE_FLOAT: int = 3 12 | const TYPE_STRING: int = 4 13 | const TYPE_VECTOR2: int = 5 14 | const TYPE_VECTOR2I: int = 6 15 | const TYPE_RECT2: int = 7 16 | const TYPE_RECT2I: int = 8 17 | const TYPE_VECTOR3: int = 9 18 | const TYPE_VECTOR3I: int = 10 19 | const TYPE_TRANSFORM2D: int = 11 20 | const TYPE_VECTOR4: int = 12 21 | const TYPE_VECTOR4I: int = 13 22 | const TYPE_PLANE: int = 14 23 | const TYPE_QUATERNION: int = 15 24 | const TYPE_AABB: int = 16 25 | const TYPE_BASIS: int = 17 26 | const TYPE_TRANSFORM3D: int = 18 27 | const TYPE_PROJECTION: int = 19 28 | const TYPE_COLOR: int = 20 29 | const TYPE_STRING_NAME: int = 21 30 | const TYPE_NODE_PATH: int = 22 31 | const TYPE_RID: int = 23 32 | const TYPE_OBJECT: int = 24 33 | const TYPE_CALLABLE: int = 25 34 | const TYPE_SIGNAL: int = 26 35 | const TYPE_DICTIONARY: int = 27 36 | const TYPE_ARRAY: int = 28 37 | const TYPE_PACKED_BYTE_ARRAY: int = 29 38 | const TYPE_PACKED_INT32_ARRAY: int = 30 39 | const TYPE_PACKED_INT64_ARRAY: int = 31 40 | const TYPE_PACKED_FLOAT32_ARRAY: int = 32 41 | const TYPE_PACKED_FLOAT64_ARRAY: int = 33 42 | const TYPE_PACKED_STRING_ARRAY: int = 34 43 | const TYPE_PACKED_VECTOR2_ARRAY: int = 35 44 | const TYPE_PACKED_VECTOR3_ARRAY: int = 36 45 | const TYPE_PACKED_COLOR_ARRAY: int = 37 46 | const TYPE_PACKED_VECTOR4_ARRAY: int = 38 47 | const TYPE_MAX: int = 39 48 | -------------------------------------------------------------------------------- /gdsbin/test/nested_if.gd: -------------------------------------------------------------------------------- 1 | class_name Nested_if 2 | 3 | func test(): 4 | # 20 levels of nesting (and then some). 5 | if true: 6 | print("1") 7 | if true: 8 | print("2") 9 | if true: 10 | print("3") 11 | if true: 12 | print("4") 13 | if true: 14 | print("5") 15 | if true: 16 | print("6") 17 | if true: 18 | print("7") 19 | if true: 20 | print("8") 21 | if true: 22 | print("9") 23 | if true: 24 | print("10") 25 | if true: 26 | print("11") 27 | if true: 28 | print("12") 29 | if true: 30 | print("13") 31 | if true: 32 | print("14") 33 | if true: 34 | print("15") 35 | if true: 36 | print("16") 37 | if true: 38 | print("17") 39 | if true: 40 | print("18") 41 | if true: 42 | print("19") 43 | if true: 44 | print("20") 45 | if false: 46 | print("End") 47 | if true: 48 | if true: 49 | if true: 50 | if true: 51 | if true: 52 | if true: 53 | if true: 54 | if true: 55 | if true: 56 | if true: 57 | if true: 58 | if true: 59 | print("This won't be printed") 60 | -------------------------------------------------------------------------------- /gdsbin/defs.gd: -------------------------------------------------------------------------------- 1 | class_name Defs 2 | 3 | ## GDScript Transpiler Import Definitions Class 4 | ## 5 | ## Properties for Transpiler 6 | ## 7 | 8 | ## Add additional python import to transpiled script if required 9 | var py_imp: bool = false 10 | ## Print additional parsing information if true 11 | var debug: bool = false 12 | ## Print transpiled script as output to console 13 | var verbose: bool = false 14 | ## Add additional python code for _init() method to transpiled script if required 15 | var init_def: bool = false 16 | ## Add additional python code for Thread class to transpiled script if required 17 | var thread_def: bool = false 18 | ## Add additional python code for resize() method to transpiled script if required 19 | var resize_def: bool = false 20 | ## Add additional python code for right() method to transpiled script if required 21 | var right_def: bool = false 22 | ## Add additional python code for left() method to transpiled script if required 23 | var left_def: bool = false 24 | ## Add additional python code for execute() method to transpiled script if required 25 | var execute_def: bool = false 26 | ## Add additional python code for execute_pipe() method to transpiled script if required 27 | var execute_pipe_def: bool = false 28 | ## Add additional python code for get_global_name() method to transpiled script if required 29 | var classname_def: bool = false 30 | ## Add additional python sys import to transpiled script if required 31 | var sys_imp: bool = false 32 | ## Add additional python subprocess import to transpiled script if required 33 | var subprocess_imp: bool = false 34 | ## Add additional python os import to transpiled script if required 35 | var os_imp: bool = false 36 | ## Add additional python math import to transpiled script if required 37 | var math_imp: bool = false 38 | ## Add additional python random import to transpiled script if required 39 | var rand_imp: bool = false 40 | ## Add additional python datetime import to transpiled script if required 41 | var datetime_imp: bool = false 42 | -------------------------------------------------------------------------------- /Godot-v.svg: -------------------------------------------------------------------------------- 1 | Godot4.5.1-stable 2 | -------------------------------------------------------------------------------- /gdsbin/tokenizer.gd: -------------------------------------------------------------------------------- 1 | class_name Tokenizer 2 | 3 | ## GDScript Transpiler Properties Class 4 | ## 5 | ## Properties for Transpiler 6 | ## 7 | var key = Key.new() 8 | var keyword = Keyword.new() 9 | 10 | ## Method to process input string and list of tokens 11 | func tokenize(input_string: String) -> Array: 12 | var delimiter : Array = ['(', ')', ':', ',', '.', '=', '+', '-', '*', '/', '<', '>', '!', '&', '|', '~', '%', ' ', '[', ']', '{', '}', '"', '\t'] 13 | const qu: String = '"' 14 | var token : Dictionary = { 15 | "#": key.KEY_NUMBERSIGN, 16 | "!": key.KEY_EXCLAM, 17 | "/": key.KEY_SLASH, 18 | "\\": key.KEY_BACKSLASH, 19 | "(": key.KEY_PARENLEFT, 20 | ")": key.KEY_PARENRIGHT, 21 | "-": key.KEY_MINUS, 22 | "+": key.KEY_PLUS, 23 | "*": key.KEY_ASTERISK, 24 | ">": key.KEY_GREATER, 25 | "<": key.KEY_LESS, 26 | ":": key.KEY_COLON, 27 | "=": key.KEY_EQUAL, 28 | "{": key.KEY_BRACELEFT, 29 | "}": key.KEY_BRACERIGHT, 30 | "\t": key.KEY_TAB, 31 | ".": key.KEY_PERIOD, 32 | ",": key.KEY_COMMA, 33 | "class_name": keyword.KW_CLASSNAME, 34 | "extends": keyword.KW_EXTENDS, 35 | "##": keyword.KW_NUMBERSIGN2, 36 | "func": keyword.KW_FUNCTION, 37 | "new": keyword.KW_NEW, 38 | "var": keyword.KW_VARIABLE, 39 | "const": keyword.KW_CONST, 40 | "for": keyword.KW_FOR, 41 | "in": keyword.KW_IN, 42 | "if": keyword.KW_IF, 43 | qu: key.KEY_QUOTEDBL 44 | } 45 | var tokens: Array = [] 46 | var buffer: String = "" 47 | var str: bool = false 48 | for ch in input_string: 49 | if ch in delimiter: 50 | if ch == '"': 51 | str = false if str else true 52 | elif str: 53 | buffer += ch 54 | continue 55 | if buffer != "": 56 | tokens.append(char_to_token(buffer, token)) 57 | buffer = "" 58 | if ch != " ": 59 | tokens.append(char_to_token(ch, token)) 60 | else: 61 | buffer += ch 62 | if buffer != "": 63 | tokens.append(char_to_token(buffer, token)) 64 | return tokens 65 | 66 | ## Convert each character to token 67 | func char_to_token(buffer: String, token_index: Dictionary): 68 | var token = Token.new() 69 | token.id = token_index[buffer] if buffer in token_index else keyword.KW_NONE 70 | token.value = buffer 71 | return token 72 | -------------------------------------------------------------------------------- /gdsbin/test/nested_match.gd: -------------------------------------------------------------------------------- 1 | class_name Nested_match 2 | 3 | func test(): 4 | # 20 levels of nesting (and then some). 5 | var number = 1234 6 | match number: 7 | 1234: 8 | print("1") 9 | match number: 10 | 1234: 11 | print("2") 12 | match number: 13 | 1234: 14 | print("3") 15 | # TODO: not working in python yet 16 | #continue 17 | _: 18 | print("Should also be printed") 19 | match number: 20 | 1234: 21 | print("4") 22 | match number: 23 | _: 24 | print("5") 25 | match number: 26 | false: 27 | print("Should not be printed") 28 | true: 29 | print("Should not be printed") 30 | "hello": 31 | print("Should not be printed") 32 | 1234: 33 | print("6") 34 | match number: 35 | _: 36 | print("7") 37 | match number: 38 | 1234: 39 | print("8") 40 | match number: 41 | _: 42 | print("9") 43 | match number: 44 | 1234: 45 | print("10") 46 | match number: 47 | _: 48 | print("11") 49 | match number: 50 | 1234: 51 | print("12") 52 | match number: 53 | _: 54 | print("13") 55 | match number: 56 | 1234: 57 | print("14") 58 | match number: 59 | _: 60 | print("15") 61 | match number: 62 | _: 63 | print("16") 64 | match number: 65 | 1234: 66 | print("17") 67 | match number: 68 | _: 69 | print("18") 70 | match number: 71 | 1234: 72 | print("19") 73 | match number: 74 | _: 75 | print("20") 76 | match number: 77 | []: 78 | print("Should not be printed") 79 | _: 80 | print("Should not be printed") 81 | 5678: 82 | print("Should not be printed either") 83 | -------------------------------------------------------------------------------- /gdsbin/test/nested_parentheses.gd: -------------------------------------------------------------------------------- 1 | class_name Nested_parentheses 2 | 3 | func test(): 4 | (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((print("Hello world!")))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 5 | 6 | print(((((((((((((((((((((((((((((((((((((((((((((((((((((((((("Hello world 2!")))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 7 | 8 | print( 9 | ( 10 | ( 11 | ( 12 | ( 13 | ( 14 | ( 15 | ( 16 | ( 17 | ( 18 | ( 19 | ( 20 | ( 21 | ( 22 | ( 23 | ( 24 | ( 25 | ( 26 | ( 27 | ( 28 | ( 29 | ( 30 | ( 31 | ( 32 | ( 33 | ( 34 | ( 35 | ( 36 | ( 37 | ( 38 | ( 39 | ( 40 | ( 41 | ( 42 | ( 43 | ( 44 | ( 45 | ( 46 | ( 47 | ( 48 | ( 49 | ( 50 | ( 51 | ( 52 | ( 53 | ( 54 | ( 55 | ( 56 | ( 57 | ( 58 | ( 59 | ( 60 | ( 61 | ( 62 | ( 63 | ( 64 | ( 65 | ( 66 | ( 67 | (2)) + ((4)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 68 | -------------------------------------------------------------------------------- /project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | [application] 12 | 13 | config/name="GDScript2PythonTranspiler" 14 | config/version="0.1.5" 15 | config/tags=PackedStringArray("godot4", "python", "testing") 16 | run/main_scene="res://gdsbin/main.tscn" 17 | config/features=PackedStringArray("4.5") 18 | run/low_processor_mode=true 19 | boot_splash/show_image=false 20 | boot_splash/fullsize=false 21 | boot_splash/use_filter=false 22 | config/icon="res://icon.svg" 23 | 24 | [display] 25 | 26 | window/size/viewport_width=1280 27 | window/size/viewport_height=720 28 | window/size/mode=4 29 | window/energy_saving/keep_screen_on=false 30 | display_server/driver.linuxbsd="wayland" 31 | window/handheld/orientation="sensor_landscape" 32 | window/size/width=1280 33 | window/size/height=720 34 | window/vsync/use_vsync=false 35 | 36 | [editor] 37 | 38 | movie_writer/mjpeg_quality=1.0 39 | 40 | [editor_plugins] 41 | 42 | enabled=PackedStringArray("res://addons/gdUnit4/plugin.cfg") 43 | 44 | [filesystem] 45 | 46 | import/blender/enabled=false 47 | 48 | [input] 49 | 50 | run_script={ 51 | "deadzone": 0.5, 52 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":16777226,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) 53 | ] 54 | } 55 | toggle_comment={ 56 | "deadzone": 0.5, 57 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":16777238,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) 58 | ] 59 | } 60 | tab={ 61 | "deadzone": 0.5, 62 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194306,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) 63 | ] 64 | } 65 | 66 | [rendering] 67 | 68 | renderer/rendering_method="gl_compatibility" 69 | renderer/rendering_method.mobile="gl_compatibility" 70 | textures/vram_compression/import_etc2_astc=true 71 | quality/driver/driver_name="GLES2" 72 | quality/intended_usage/framebuffer_allocation=1 73 | quality/intended_usage/framebuffer_allocation.mobile=1 74 | vram_compression/import_etc=true 75 | vram_compression/import_etc2=true 76 | environment/default_clear_color=Color(0.1245, 0.142775, 0.15, 1) 77 | environment/default_environment="res://default_env.tres" 78 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to GDScript Transpiler 2 | 3 | Thank you for considering contributing to GDScript Transpiler! 4 | 5 | We appreciate your input and want to make the contribution process as easy and transparent as possible. 6 | 7 | Whether you want to report a bug, discuss code improvements, submit a fix, propose new features, or become a maintainer, we welcome your involvement. 8 | 9 | ## Development on Codeberg 10 | We use Codeberg to host our code, track issues and feature requests, and accept pull requests. 11 | 12 | It's recommended to familiarize yourself with Codeberg's features and workflow to participate effectively. 13 | 14 | ## Codeberg Flow 15 | We follow the Codeberg Flow for making code changes. 16 | 17 | This means that all code modifications should be proposed through pull requests. 18 | 19 | Pull requests provide a structured and collaborative way to review and discuss code changes. 20 | 21 | If you'd like to contribute, please follow these steps: 22 | 23 | 1. Select an open issue to work on or create a new issue if none exists. 24 | 2. Fork the repository and create a branch from the `dev` branch. 25 | - Use the issue number as the branch name, e.g., GD-111. 26 | - Assign the issue to yourself and set its status to "In Progress." 27 | 3. If you have made changes to the code that should be tested, please include appropriate tests. 28 | 4. If you have modified any APIs, ensure that the documentation is updated accordingly. 29 | 5. Create a pull request and provide information in the "Why" and "What" sections: 30 | - Link the pull request to the corresponding issue. 31 | - Assign the pull request to yourself. 32 | - Make sure each pull request is associated with only one issue. 33 | - If the pull request is still in progress, mark it as a draft. 34 | - Ensure that the continuous integration (CI) process passes successfully. 35 | 6. Submit the pull request! 36 | 37 | ## License 38 | By contributing to this project, you agree that your contributions will be licensed under the same [MIT License](https://codeberg.org/LinuxUserGD/gdscript-transpiler-bin/src/branch/dev/LICENSE) that covers the project. 39 | 40 | If you have any concerns, please reach out to the maintainers. 41 | 42 | ## Reporting Bugs 43 | If you encounter any bugs or issues, please use Codeberg's issue tracking system. 44 | 45 | You can report a bug by [opening a new issue](https://codeberg.org/LinuxUserGD/gdscript-transpiler-bin/issues/new?template=.gitea%2fISSUE_TEMPLATE%2fbug.md). 46 | 47 | When submitting a bug report, please provide detailed information, including the steps to reproduce the issue, relevant background information, and sample code if possible. 48 | 49 | ## Coding Style 50 | To maintain code consistency, please adhere to the following coding style guides: 51 | - [Godot's GDScript Conventions](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_styleguide.html) 52 | 53 | ## References 54 | This document was adapted from the open-source contribution guidelines for [GdUnit4](https://github.com/MikeSchulze/gdUnit4/blob/master/CONTRIBUTING.md) 55 | -------------------------------------------------------------------------------- /.forgejo/workflows/upload.yml: -------------------------------------------------------------------------------- 1 | name: Upload 2 | # Only trigger, when the build workflow succeeded 3 | on: 4 | workflow_run: 5 | workflows: ["Template"] 6 | types: 7 | - completed 8 | 9 | concurrency: 10 | group: ${{ github.workflow }}-${{ github.ref }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | build-linux: 15 | runs-on: linux-docker 16 | if: ${{ github.event.workflow_run.conclusion == 'success' }} 17 | name: Linux itch.io Upload 18 | outputs: 19 | status: ${{ steps.early.outputs.status }} 20 | steps: 21 | - name: Download artifact from build 22 | uses: bettermarks/action-artifact-download@0.5.1 23 | with: 24 | repo: LinuxUserGD/gdscript-transpiler-bin 25 | token: ${{ secrets.GITHUB_TOKEN }} 26 | artifact_name: Linux Build 27 | rename: linux.zip 28 | wait_seconds: 20 29 | 30 | - name: Download artifact from build 31 | uses: bettermarks/action-artifact-download@0.5.1 32 | with: 33 | repo: LinuxUserGD/gdscript-transpiler-bin 34 | token: ${{ secrets.GITHUB_TOKEN }} 35 | artifact_name: MacOS Build 36 | rename: macOS.zip 37 | wait_seconds: 20 38 | 39 | - name: Download artifact from build 40 | uses: bettermarks/action-artifact-download@0.5.1 41 | with: 42 | repo: LinuxUserGD/gdscript-transpiler-bin 43 | token: ${{ secrets.GITHUB_TOKEN }} 44 | artifact_name: Windows Build 45 | rename: windows.zip 46 | wait_seconds: 20 47 | 48 | - name: Extracting linux.zip 49 | shell: bash 50 | run: | 51 | sudo apt-get update && sudo apt-get install unzip 52 | unzip linux.zip 53 | rm linux.zip 54 | 55 | - name: Uploading linux binary 56 | uses: yeslayla/butler-publish-itchio-action@master 57 | env: 58 | BUTLER_CREDENTIALS: ${{ secrets.BUTLER_CREDENTIALS }} 59 | CHANNEL: linux 60 | ITCH_GAME: gdscript-transpiler-bin 61 | ITCH_USER: linuxusergd 62 | PACKAGE: gds 63 | 64 | - name: Extracting macOS.zip 65 | shell: bash 66 | run: | 67 | rm -rf gds 68 | unzip macOS.zip 69 | rm macOS.zip 70 | 71 | - name: Uploading macOS binary 72 | uses: yeslayla/butler-publish-itchio-action@master 73 | env: 74 | BUTLER_CREDENTIALS: ${{ secrets.BUTLER_CREDENTIALS }} 75 | CHANNEL: mac 76 | ITCH_GAME: gdscript-transpiler-bin 77 | ITCH_USER: linuxusergd 78 | PACKAGE: gds 79 | 80 | - name: Extracting windows.zip 81 | shell: bash 82 | run: | 83 | rm -rf gds 84 | unzip windows.zip 85 | rm windows.zip 86 | 87 | - name: Uploading windows binary 88 | uses: yeslayla/butler-publish-itchio-action@master 89 | env: 90 | BUTLER_CREDENTIALS: ${{ secrets.BUTLER_CREDENTIALS }} 91 | CHANNEL: windows 92 | ITCH_GAME: gdscript-transpiler-bin 93 | ITCH_USER: linuxusergd 94 | PACKAGE: gds.exe 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |
4 | GDScript to Python to C Transpiler 5 | 6 | [![Godot](Godot-v.svg)](https://downloads.tuxfamily.org/godotengine/4.0/) 7 | [![MIT license](mit.svg)](LICENSE.md) 8 | [![Python](python.svg)](https://www.python.org/) 9 |

10 | 11 |
12 | 13 | `gdscript-transpiler-bin` is a GDScript compiler (using [Nuitka](https://github.com/Nuitka/Nuitka)), minimal scripts can be transpiled to Python. 14 | 15 | Binary builds are compiled using [Forgejo Actions](https://codeberg.org/LinuxUserGD/gdscript-transpiler-bin/actions) for Alpine Linux, macOS and Windows x86_64. 16 | 17 | Other compatible platforms: Android (aarch64 and x86_64). 18 | 19 | Also see [generated Python source from GDScript](https://codeberg.org/LinuxUserGD/gdscript-transpiler-bin/src/branch/python). 20 | 21 | 22 | [![Video](preview.gif)](preview.gif) 23 | 24 | ## Example 25 | 26 | ``` 27 | git clone https://codeberg.org/LinuxUserGD/gdscript-transpiler-bin.git 28 | 29 | cd gdscript-transpiler-bin 30 | 31 | git submodule update --init --remote --progress 32 | ``` 33 | 34 | ### Godot Engine command line (stage0) 35 | 36 | - `./godot4 -s bin/gds.gd --headless help` 37 | 38 | - `./godot4 -s bin/gds.gd --headless run=bin/gds.gd` (for running GDScript directly using x-python) 39 | 40 | - `./godot4 -s bin/gds.gd --headless format=bin/gds.gd` (for generating Python project) 41 | 42 | - `./godot4 -s bin/gds.gd --headless compile=bin/gds.gd` (for compiling GDScript to binary using Clang and Nuitka) 43 | 44 | ### Python environment (stage1) 45 | Installing python gds 46 | ``` 47 | python -m pip install gdsbin 48 | 49 | python -m pip install git+https://codeberg.org/LinuxUserGD/gdscript-transpiler-bin.git@python 50 | ``` 51 | 52 | - `python -m gdsbin help` 53 | 54 | - `python -m gdsbin run=bin/gds.gd` 55 | 56 | - `python -m gdsbin format=bin/gds.gd` 57 | 58 | - `python -m gdsbin compile=bin/gds.gd` 59 | 60 | ### Nuitka compiled binary (stage2) 61 | Installing gds binary (available at [itch.io](https://linuxusergd.itch.io/gdscript-transpiler-bin)) 62 | ``` 63 | unzip gdscript-transpiler-bin.zip 64 | cd gdscript-transpiler-bin 65 | chmod +x gds 66 | ``` 67 | 68 | - `./gds[.exe] help` 69 | 70 | - `./gds[.exe] run=bin/gds.gd` 71 | 72 | - `./gds[.exe] format=bin/gds.gd` 73 | 74 | - `./gds[.exe] compile=bin/gds.gd` 75 | 76 | ## Benchmark 77 | 78 | Time for running GDScript code: 79 | 80 | ```gdscript 81 | func string() -> int: 82 | var x: String = "" 83 | for i in range(0, 300000): 84 | x += " " 85 | return x.length() 86 | 87 | func add() -> int: 88 | var x: int = -100000000 89 | for i in range(0, 100000000): 90 | x += 1 91 | return x 92 | ``` 93 | 94 | | | Godot | Python | Nuitka 95 | |--------------|------------|------------|------------ 96 | | benchmark.gd | 11.639s | 4.678s | 1.857s 97 | 98 | ## License 99 | 100 | ### See [LICENSE](LICENSE.md) and [CREDITS](CREDITS.md) (third-party licenses) 101 | -------------------------------------------------------------------------------- /docker/run.sh: -------------------------------------------------------------------------------- 1 | [ "${portage_upgrade}" = true ] && echo "Upgrading image..." || true && \ 2 | [ "${portage_upgrade}" = false ] && echo "Installing image..." || true && \ 3 | rm -rf /etc/portage/package.use/* /etc/portage/package.accept_keywords/* /etc/portage/package.mask/* && \ 4 | echo '*/* ~amd64' > /etc/portage/package.accept_keywords/base.conf && \ 5 | echo 'dev-lang/python **' > /etc/portage/package.accept_keywords/python.conf && \ 6 | echo '*/* compiler-rt default-compiler-rt default-libcxx default-lld libcxx -offload openmp -polly sanitize llvm-libunwind clang' > /etc/portage/package.use/clang.conf && \ 7 | echo '*/* full-stdlib sqlite' > /etc/portage/package.use/python.conf && \ 8 | echo 'net-misc/curl -curl_quic_openssl -quic -http3 -httpsrr -adns' > /etc/portage/package.use/curl.conf && \ 9 | echo 'dev-vcs/git -perl' > /etc/portage/package.use/git.conf && \ 10 | echo 'app-alternatives/ninja -reference samurai' > /etc/portage/package.use/ninja.conf && \ 11 | echo 'sys-devel/gcc' > /etc/portage/package.mask/gcc.conf && \ 12 | echo 'EMERGE_DEFAULT_OPTS="--jobs 3"' >> /etc/portage/make.conf && \ 13 | echo 'LTO_ERR="-Werror=odr -Werror=conditional-type-mismatch -Werror=pointer-type-mismatch -Werror=selector-type-mismatch -Werror=strict-aliasing -Wno-implicit-function-declaration -Wno-sizeof-pointer-memaccess"' >> /etc/portage/make.conf && \ 14 | echo 'COMMON_FLAGS="-O3 -pipe -march=native -g0 -D_FORTIFY_SOURCE=3 -flto=thin"' >> /etc/portage/make.conf && \ 15 | echo 'CFLAGS="${COMMON_FLAGS}"' >> /etc/portage/make.conf && \ 16 | echo 'CXXFLAGS="${COMMON_FLAGS} ${LTO_ERR} -stdlib=libc++"' >> /etc/portage/make.conf && \ 17 | echo 'LDFLAGS="-Wl,-O3 -Wl,--as-needed -Wl,--strip-debug -Wl,--undefined-version -Wl,--icf=safe -Wl,--threads=4 -rtlib=compiler-rt -unwindlib=libunwind -stdlib=libc++ -fuse-ld=lld"' >> /etc/portage/make.conf && \ 18 | echo 'LD="ld.lld"' >> /etc/portage/make.conf && \ 19 | echo 'FEATURES="-config-protect-if-modified"' >> /etc/portage/make.conf && \ 20 | echo 'NINJA=samu' >> /etc/portage/make.conf && \ 21 | perl -i -ne 'print if ! $x{$_}++' /etc/portage/make.conf && \ 22 | wget --progress=dot:mega -O - https://github.com/gentoo-mirror/gentoo/archive/master.tar.gz | tar -xz && \ 23 | mv gentoo-master /var/db/repos/gentoo && \ 24 | echo '-5' | etc-update && \ 25 | emerge net-misc/curl --newuse --changed-use && \ 26 | emerge app-alternatives/ninja --newuse --changed-use && \ 27 | emerge dev-lang/go dev-python/nuitka dev-util/patchelf dev-vcs/git --newuse --changed-use && \ 28 | emerge -1 app-eselect/eselect-repository --newuse --changed-use && \ 29 | eselect repository add 12101111-overlay git https://github.com/12101111/overlay.git &> /dev/null || true && \ 30 | emerge --sync 12101111-overlay && \ 31 | eselect repository add clang-musl git https://github.com/clang-musl-overlay/clang-musl-overlay.git &> /dev/null || true && \ 32 | emerge --sync clang-musl && \ 33 | emerge llvm-runtimes/libatomic-stub --newuse --changed-use && \ 34 | emerge net-libs/nodejs --newuse --changed-use && \ 35 | emerge sys-devel/llvm-conf --newuse --changed-use && \ 36 | emerge --depclean && \ 37 | [ "${portage_upgrade}" = true ] && emerge --oneshot --update --newuse --changed-use --deep --with-bdeps=y --keep-going @installed --exclude=sys-devel/gcc --exclude=net-misc/iputils || true && \ 38 | [ "${portage_upgrade}" = true ] && emerge --depclean || true && \ 39 | rm -r /var/db/repos/* /var/cache/distfiles/* 40 | -------------------------------------------------------------------------------- /gdsbin/fonts/LICENSE.Hack.md: -------------------------------------------------------------------------------- 1 | The work in the Hack project is Copyright 2018 Source Foundry Authors and licensed under the MIT License 2 | 3 | The work in the DejaVu project was committed to the public domain. 4 | 5 | Bitstream Vera Sans Mono Copyright 2003 Bitstream Inc. and licensed under the Bitstream Vera License with Reserved Font Names "Bitstream" and "Vera" 6 | 7 | ### MIT License 8 | 9 | Copyright (c) 2018 Source Foundry Authors 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in all 19 | copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | SOFTWARE. 28 | 29 | ### BITSTREAM VERA LICENSE 30 | 31 | Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. 32 | 33 | Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: 34 | 35 | The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. 36 | 37 | The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". 38 | 39 | This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. 40 | 41 | The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. 42 | 43 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. 44 | 45 | Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org. 46 | -------------------------------------------------------------------------------- /.forgejo/workflows/template.yml: -------------------------------------------------------------------------------- 1 | name: Template 2 | on: 3 | push: 4 | branches: 5 | - 'dev' 6 | 7 | concurrency: 8 | group: ${{ github.workflow }}-${{ github.ref }} 9 | cancel-in-progress: true 10 | 11 | jobs: 12 | build-linux: 13 | permissions: write-all 14 | runs-on: codeberg-tiny-lazy 15 | container: 16 | image: docker.io/library/node:current-alpine 17 | name: ${{ matrix.name }} 18 | outputs: 19 | status: ${{ steps.early.outputs.status }} 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | include: 24 | - name: Minimal Template (target=editor, everything disabled) 25 | cache-name: linux-template-minimal 26 | target: editor 27 | tests: false 28 | artifact: true 29 | steps: 30 | - name: Check-out repository 31 | uses: https://code.forgejo.org/actions/checkout@v4.3.0 32 | 33 | - name: Run script 34 | id: early 35 | env: 36 | CUSTOMTOKEN: ${{ secrets.GITHUB_TOKEN }} 37 | run: | 38 | apk add --no-cache python3 py3-pip git ruff 39 | rm *.import 40 | rm project.godot 41 | rm -rf addons docker gdUnit4 zig-template 42 | git clone https://oauth:${{ secrets.GITHUB_TOKEN }}@codeberg.org/LinuxUserGD/gdscript-transpiler-bin.git -b python 43 | python3 gdscript-transpiler-bin/bin/gds.py format=bin/gds.gd 44 | python3 gdscript-transpiler-bin/bin/gds.py setup=setup.py 45 | cp gdscript-transpiler-bin/requirements.txt . 46 | python3 -m pip install . --no-cache-dir --no-deps --break-system-packages 47 | rm -rf gdsbin.egg-info _build 48 | rm pyproject.toml 49 | find . ! -path "./gdscript-transpiler-bin/*" -name "*.py" -type f | xargs rm -- 50 | python3 -m gdsbin format=bin/gds.gd 51 | python3 -m gdsbin setup=setup.py 52 | echo "Uploading files..." 53 | dir=$(find */ -maxdepth 0 -type d ! -name "gdscript-transpiler-bin") 54 | cd gdscript-transpiler-bin 55 | rm -rf $(ls | grep -v "requirements.txt") 56 | for i in $dir; do mkdir ${i} ; done 57 | for i in $dir; do cp -r "../${i}"*.py ${i} ; done 58 | mkdir -p gdsbin/test; cp -r ../gdsbin/test/*.py gdsbin/test/ 59 | for i in $(echo "setup.py pyproject.toml README.md CONTRIBUTING.md CREDITS.md LICENSE.md icon.svg python.svg mit.svg Godot-v.svg"); do cp ../${i} . ; done 60 | git config --global user.name "LinuxUserGD" 61 | git config --global user.email "hugegameartgd@gmail.com" 62 | git add -A 63 | [ -n "$(git diff-index HEAD)" ] && { echo "New update"; git commit -m "update python files" && git push origin python; } || { echo "Files identical"; exit 0; } 64 | cd .. 65 | echo ${PWD} 66 | 67 | 68 | deploy-linux: 69 | runs-on: linux-docker 70 | container: 71 | image: codeberg.org/linuxusergd/gdsbin-amd64-musl-llvm:latest 72 | name: Deploy (Alpine Linux x86_64) 73 | needs: build-linux 74 | 75 | steps: 76 | - name: Check-out repository 77 | uses: https://code.forgejo.org/actions/checkout@main 78 | with: 79 | ref: python 80 | 81 | - name: Compile gdscript-transpiler-bin 82 | env: 83 | CUSTOMTOKEN: ${{ secrets.GITHUB_TOKEN }} 84 | run: | 85 | llvm-conf 1 86 | . /etc/profile 87 | env-update 88 | source /etc/portage/make.conf 89 | python3 -m nuitka bin/gds.py --onefile --lto=yes --static-libpython=no --clang --assume-yes-for-downloads --remove-output -o gds 90 | export BUTLER_API_KEY=${{ secrets.BUTLER_CREDENTIALS }} 91 | echo $BUTLER_API_KEY > key.txt 92 | git clone https://github.com/LinuxUserGD/butler.git 93 | pushd butler 94 | go build 95 | popd 96 | ./butler/butler -i key.txt push gds linuxusergd/gdscript-transpiler-bin:linux 97 | 98 | - name: Upload main.dist 99 | uses: actions/upload-artifact@v3 100 | with: 101 | name: Linux Build 102 | path: /home/runner/work/gdscript-transpiler-bin/gdscript-transpiler-bin/gds 103 | -------------------------------------------------------------------------------- /gdsbin/fonts/LICENSE.Noto.txt: -------------------------------------------------------------------------------- 1 | This Font Software is licensed under the SIL Open Font License, 2 | Version 1.1. 3 | 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | ----------------------------------------------------------- 8 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 9 | ----------------------------------------------------------- 10 | 11 | PREAMBLE 12 | The goals of the Open Font License (OFL) are to stimulate worldwide 13 | development of collaborative font projects, to support the font 14 | creation efforts of academic and linguistic communities, and to 15 | provide a free and open framework in which fonts may be shared and 16 | improved in partnership with others. 17 | 18 | The OFL allows the licensed fonts to be used, studied, modified and 19 | redistributed freely as long as they are not sold by themselves. The 20 | fonts, including any derivative works, can be bundled, embedded, 21 | redistributed and/or sold with any software provided that any reserved 22 | names are not used by derivative works. The fonts and derivatives, 23 | however, cannot be released under any other type of license. The 24 | requirement for fonts to remain under this license does not apply to 25 | any document created using the fonts or their derivatives. 26 | 27 | DEFINITIONS 28 | "Font Software" refers to the set of files released by the Copyright 29 | Holder(s) under this license and clearly marked as such. This may 30 | include source files, build scripts and documentation. 31 | 32 | "Reserved Font Name" refers to any names specified as such after the 33 | copyright statement(s). 34 | 35 | "Original Version" refers to the collection of Font Software 36 | components as distributed by the Copyright Holder(s). 37 | 38 | "Modified Version" refers to any derivative made by adding to, 39 | deleting, or substituting -- in part or in whole -- any of the 40 | components of the Original Version, by changing formats or by porting 41 | the Font Software to a new environment. 42 | 43 | "Author" refers to any designer, engineer, programmer, technical 44 | writer or other person who contributed to the Font Software. 45 | 46 | PERMISSION & CONDITIONS 47 | Permission is hereby granted, free of charge, to any person obtaining 48 | a copy of the Font Software, to use, study, copy, merge, embed, 49 | modify, redistribute, and sell modified and unmodified copies of the 50 | Font Software, subject to the following conditions: 51 | 52 | 1) Neither the Font Software nor any of its individual components, in 53 | Original or Modified Versions, may be sold by itself. 54 | 55 | 2) Original or Modified Versions of the Font Software may be bundled, 56 | redistributed and/or sold with any software, provided that each copy 57 | contains the above copyright notice and this license. These can be 58 | included either as stand-alone text files, human-readable headers or 59 | in the appropriate machine-readable metadata fields within text or 60 | binary files as long as those fields can be easily viewed by the user. 61 | 62 | 3) No Modified Version of the Font Software may use the Reserved Font 63 | Name(s) unless explicit written permission is granted by the 64 | corresponding Copyright Holder. This restriction only applies to the 65 | primary font name as presented to the users. 66 | 67 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 68 | Software shall not be used to promote, endorse or advertise any 69 | Modified Version, except to acknowledge the contribution(s) of the 70 | Copyright Holder(s) and the Author(s) or with their explicit written 71 | permission. 72 | 73 | 5) The Font Software, modified or unmodified, in part or in whole, 74 | must be distributed entirely under this license, and must not be 75 | distributed under any other license. The requirement for fonts to 76 | remain under this license does not apply to any document created using 77 | the Font Software. 78 | 79 | TERMINATION 80 | This license becomes null and void if any of the above conditions are 81 | not met. 82 | 83 | DISCLAIMER 84 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 85 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 86 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 87 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 88 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 89 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 90 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 91 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 92 | OTHER DEALINGS IN THE FONT SOFTWARE. 93 | -------------------------------------------------------------------------------- /gdsbin/main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=8 format=3 uid="uid://bb4hpvw0tq6yt"] 2 | 3 | [ext_resource type="Theme" uid="uid://bwuol0nxm8rsj" path="res://gdsbin/resources/theme.tres" id="1_b4qlw"] 4 | [ext_resource type="Script" uid="uid://c56mduespamfh" path="res://gdsbin/main_window.gd" id="2_cf6o8"] 5 | [ext_resource type="Script" uid="uid://dq0ro428q1yxf" path="res://gdsbin/script_editor.gd" id="3_d7aim"] 6 | [ext_resource type="FontFile" uid="uid://decvm47txmafw" path="res://gdsbin/fonts/noto_sans_regular.ttf" id="4_hv1ml"] 7 | [ext_resource type="Script" uid="uid://c4qpli2ohyfbj" path="res://gdsbin/run_button.gd" id="5_d1ogv"] 8 | 9 | [sub_resource type="CodeHighlighter" id="CodeHighlighter_wdykl"] 10 | number_color = Color(1, 0.666667, 0.137255, 1) 11 | symbol_color = Color(1, 1, 1, 1) 12 | function_color = Color(0.27451, 0.47451, 0.65098, 1) 13 | 14 | [sub_resource type="CodeHighlighter" id="CodeHighlighter_r1olw"] 15 | number_color = Color(1, 0.666667, 0.137255, 1) 16 | symbol_color = Color(1, 1, 1, 1) 17 | function_color = Color(0.27451, 0.47451, 0.65098, 1) 18 | 19 | [node name="MainWindow" type="Control"] 20 | layout_mode = 3 21 | anchors_preset = 15 22 | anchor_right = 1.0 23 | anchor_bottom = 1.0 24 | grow_horizontal = 2 25 | grow_vertical = 2 26 | theme = ExtResource("1_b4qlw") 27 | script = ExtResource("2_cf6o8") 28 | 29 | [node name="HSplitContainer" type="HSplitContainer" parent="."] 30 | layout_mode = 1 31 | anchors_preset = 15 32 | anchor_right = 1.0 33 | anchor_bottom = 1.0 34 | grow_horizontal = 2 35 | grow_vertical = 2 36 | split_offset = 640 37 | 38 | [node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer"] 39 | layout_mode = 2 40 | 41 | [node name="ScriptEditor" type="TextEdit" parent="HSplitContainer/VBoxContainer"] 42 | layout_mode = 2 43 | size_flags_vertical = 3 44 | theme = ExtResource("1_b4qlw") 45 | text = "extends Node 46 | 47 | func _ready(): 48 | pass" 49 | caret_blink = true 50 | syntax_highlighter = SubResource("CodeHighlighter_wdykl") 51 | highlight_all_occurrences = true 52 | highlight_current_line = true 53 | draw_tabs = true 54 | script = ExtResource("3_d7aim") 55 | 56 | [node name="RunButton" type="Button" parent="HSplitContainer/VBoxContainer/ScriptEditor"] 57 | layout_mode = 1 58 | anchors_preset = 1 59 | anchor_left = 1.0 60 | anchor_right = 1.0 61 | offset_left = -80.0 62 | offset_bottom = 33.0 63 | grow_horizontal = 0 64 | theme_override_fonts/font = ExtResource("4_hv1ml") 65 | text = "Run" 66 | script = ExtResource("5_d1ogv") 67 | metadata/_edit_layout_mode = 1 68 | 69 | [node name="ok" type="HSplitContainer" parent="HSplitContainer"] 70 | layout_mode = 2 71 | split_offset = 640 72 | 73 | [node name="VBoxContainer2" type="VBoxContainer" parent="HSplitContainer/ok"] 74 | layout_mode = 2 75 | 76 | [node name="ScriptEditor" type="TextEdit" parent="HSplitContainer/ok/VBoxContainer2"] 77 | layout_mode = 2 78 | size_flags_vertical = 3 79 | theme = ExtResource("1_b4qlw") 80 | editable = false 81 | caret_blink = true 82 | syntax_highlighter = SubResource("CodeHighlighter_r1olw") 83 | highlight_all_occurrences = true 84 | highlight_current_line = true 85 | draw_tabs = true 86 | script = ExtResource("3_d7aim") 87 | 88 | [node name="RunButton2" type="Button" parent="HSplitContainer/ok/VBoxContainer2/ScriptEditor"] 89 | layout_mode = 1 90 | anchors_preset = 1 91 | anchor_left = 1.0 92 | anchor_right = 1.0 93 | offset_left = -80.0 94 | offset_bottom = 33.0 95 | grow_horizontal = 0 96 | theme_override_fonts/font = ExtResource("4_hv1ml") 97 | text = "Run" 98 | script = ExtResource("5_d1ogv") 99 | metadata/_edit_layout_mode = 1 100 | 101 | [node name="OutputPanel" type="PanelContainer" parent="HSplitContainer/ok"] 102 | layout_mode = 2 103 | 104 | [node name="ErrorLabel" type="Label" parent="HSplitContainer/ok/OutputPanel"] 105 | layout_mode = 2 106 | size_flags_vertical = 0 107 | theme_override_colors/font_color = Color(0.772549, 0, 0, 1) 108 | theme_override_fonts/font = ExtResource("4_hv1ml") 109 | clip_text = true 110 | 111 | [node name="RichTextLabel" type="RichTextLabel" parent="HSplitContainer/ok/OutputPanel"] 112 | layout_mode = 2 113 | focus_mode = 2 114 | scroll_following = true 115 | selection_enabled = true 116 | 117 | [node name="EngineVersion" type="Label" parent="."] 118 | modulate = Color(1, 1, 1, 0.501961) 119 | layout_mode = 1 120 | anchors_preset = 1 121 | anchor_left = 1.0 122 | anchor_right = 1.0 123 | offset_left = -132.0 124 | offset_top = 9.0 125 | offset_right = -15.0 126 | offset_bottom = 46.0 127 | grow_horizontal = 0 128 | metadata/_edit_layout_mode = 1 129 | 130 | [connection signal="text_changed" from="HSplitContainer/VBoxContainer/ScriptEditor" to="HSplitContainer/VBoxContainer/ScriptEditor" method="_on_script_editor_text_changed"] 131 | [connection signal="pressed" from="HSplitContainer/VBoxContainer/ScriptEditor/RunButton" to="HSplitContainer/VBoxContainer/ScriptEditor" method="_run_button_pressed"] 132 | [connection signal="pressed" from="HSplitContainer/ok/VBoxContainer2/ScriptEditor/RunButton2" to="HSplitContainer/ok/VBoxContainer2/ScriptEditor" method="_on_run_button_2_pressed"] 133 | -------------------------------------------------------------------------------- /gdsbin/resources/theme.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Theme" load_steps=10 format=3 uid="uid://bwuol0nxm8rsj"] 2 | 3 | [ext_resource type="FontFile" uid="uid://bwt6t2q5kbjbe" path="res://gdsbin/fonts/hack_regular.ttf" id="1_1sbn2"] 4 | 5 | [sub_resource type="StyleBoxFlat" id="1"] 6 | bg_color = Color(0.223529, 0.239216, 0.25098, 1) 7 | corner_radius_top_left = 3 8 | corner_radius_top_right = 3 9 | corner_radius_bottom_right = 3 10 | corner_radius_bottom_left = 3 11 | corner_detail = 4 12 | 13 | [sub_resource type="StyleBoxFlat" id="2"] 14 | bg_color = Color(0.223529, 0.239216, 0.25098, 1) 15 | draw_center = false 16 | border_width_left = 1 17 | border_width_top = 1 18 | border_width_right = 1 19 | border_width_bottom = 1 20 | border_color = Color(0.415686, 0.658824, 1, 1) 21 | corner_radius_top_left = 3 22 | corner_radius_top_right = 3 23 | corner_radius_bottom_right = 3 24 | corner_radius_bottom_left = 3 25 | corner_detail = 4 26 | 27 | [sub_resource type="StyleBoxFlat" id="3"] 28 | bg_color = Color(0.28192, 0.304768, 0.32, 1) 29 | corner_radius_top_left = 3 30 | corner_radius_top_right = 3 31 | corner_radius_bottom_right = 3 32 | corner_radius_bottom_left = 3 33 | corner_detail = 4 34 | 35 | [sub_resource type="StyleBoxFlat" id="4"] 36 | bg_color = Color(0.223529, 0.239216, 0.25098, 1) 37 | corner_radius_top_left = 3 38 | corner_radius_top_right = 3 39 | corner_radius_bottom_right = 3 40 | corner_radius_bottom_left = 3 41 | corner_detail = 4 42 | 43 | [sub_resource type="StyleBoxFlat" id="5"] 44 | bg_color = Color(0.1782, 0.190662, 0.2, 1) 45 | corner_radius_top_left = 3 46 | corner_radius_top_right = 3 47 | corner_radius_bottom_right = 3 48 | corner_radius_bottom_left = 3 49 | corner_detail = 4 50 | 51 | [sub_resource type="StyleBoxFlat" id="6"] 52 | content_margin_left = 8.0 53 | content_margin_top = 8.0 54 | content_margin_right = 8.0 55 | content_margin_bottom = 8.0 56 | bg_color = Color(0.18375, 0.202519, 0.21, 1) 57 | 58 | [sub_resource type="StyleBoxFlat" id="7"] 59 | content_margin_left = 16.0 60 | bg_color = Color(0.14926, 0.161704, 0.17, 1) 61 | 62 | [sub_resource type="StyleBoxFlat" id="8"] 63 | content_margin_left = 10.0 64 | content_margin_top = 4.0 65 | content_margin_right = 10.0 66 | content_margin_bottom = 4.0 67 | bg_color = Color(0, 0, 0, 0.54902) 68 | corner_radius_top_left = 3 69 | corner_radius_top_right = 3 70 | corner_radius_bottom_right = 3 71 | corner_radius_bottom_left = 3 72 | corner_detail = 4 73 | 74 | [resource] 75 | default_font = ExtResource("1_1sbn2") 76 | default_font_size = 15 77 | Button/colors/font_color = Color(1, 1, 1, 1) 78 | Button/colors/font_color_disabled = Color(0.9, 0.9, 0.9, 0.2) 79 | Button/colors/font_color_hover = Color(0.941176, 0.941176, 0.941176, 1) 80 | Button/colors/font_color_pressed = Color(1, 1, 1, 1) 81 | Button/constants/hseparation = 2 82 | Button/fonts/font = ExtResource("1_1sbn2") 83 | Button/styles/disabled = SubResource("1") 84 | Button/styles/focus = SubResource("2") 85 | Button/styles/hover = SubResource("3") 86 | Button/styles/normal = SubResource("4") 87 | Button/styles/pressed = SubResource("5") 88 | PanelContainer/styles/panel = SubResource("6") 89 | TextEdit/colors/background_color = Color(0.1445, 0.162775, 0.17, 1) 90 | TextEdit/colors/bookmark_color = Color(0.08, 0.49, 0.98, 1) 91 | TextEdit/colors/brace_mismatch_color = Color(1, 0.2, 0.2, 1) 92 | TextEdit/colors/breakpoint_color = Color(0.8, 0.8, 0.4, 0.2) 93 | TextEdit/colors/caret_background_color = Color(0, 0, 0, 1) 94 | TextEdit/colors/caret_color = Color(0.878431, 0.878431, 0.878431, 1) 95 | TextEdit/colors/code_folding_color = Color(0.8, 0.8, 0.8, 0.8) 96 | TextEdit/colors/completion_background_color = Color(0.172549, 0.164706, 0.196078, 1) 97 | TextEdit/colors/completion_existing_color = Color(0.87451, 0.87451, 0.87451, 0.129412) 98 | TextEdit/colors/completion_font_color = Color(0.666667, 0.666667, 0.666667, 1) 99 | TextEdit/colors/completion_scroll_color = Color(1, 1, 1, 1) 100 | TextEdit/colors/completion_selected_color = Color(0.262745, 0.258824, 0.266667, 1) 101 | TextEdit/colors/current_line_color = Color(0.25, 0.25, 0.26, 0.8) 102 | TextEdit/colors/executing_line_color = Color(0.2, 0.8, 0.2, 0.4) 103 | TextEdit/colors/font_color = Color(0.878431, 0.878431, 0.878431, 1) 104 | TextEdit/colors/font_color_readonly = Color(0.878431, 0.878431, 0.878431, 0.5) 105 | TextEdit/colors/font_color_selected = Color(0, 0, 0, 1) 106 | TextEdit/colors/font_readonly_color = Color(0, 0, 0, 1) 107 | TextEdit/colors/function_color = Color(0.4, 0.635294, 0.807843, 1) 108 | TextEdit/colors/line_number_color = Color(0.666667, 0.666667, 0.666667, 0.4) 109 | TextEdit/colors/mark_color = Color(1, 0.4, 0.4, 0.4) 110 | TextEdit/colors/member_variable_color = Color(0.901961, 0.305882, 0.34902, 1) 111 | TextEdit/colors/number_color = Color(0.921569, 0.584314, 0.196078, 1) 112 | TextEdit/colors/safe_line_number_color = Color(0.666667, 0.784314, 0.666667, 0.6) 113 | TextEdit/colors/selection_color = Color(0.490196, 0.490196, 0.490196, 1) 114 | TextEdit/colors/symbol_color = Color(0.941176, 0.941176, 0.941176, 1) 115 | TextEdit/colors/word_highlighted_color = Color(0.8, 0.9, 0.9, 0.15) 116 | TextEdit/constants/completion_lines = 7 117 | TextEdit/constants/completion_max_width = 50 118 | TextEdit/constants/completion_scroll_width = 3 119 | TextEdit/constants/line_spacing = 4 120 | TextEdit/fonts/font = ExtResource("1_1sbn2") 121 | TextEdit/icons/fold = null 122 | TextEdit/icons/folded = null 123 | TextEdit/icons/space = null 124 | TextEdit/icons/tab = null 125 | TextEdit/styles/completion = null 126 | TextEdit/styles/focus = null 127 | TextEdit/styles/normal = SubResource("7") 128 | TextEdit/styles/read_only = null 129 | TooltipLabel/colors/font_color = Color(0.941176, 0.941176, 0.941176, 1) 130 | TooltipLabel/colors/font_color_shadow = Color(0, 0, 0, 0) 131 | TooltipLabel/constants/shadow_offset_x = 0 132 | TooltipLabel/constants/shadow_offset_y = 0 133 | TooltipLabel/fonts/font = ExtResource("1_1sbn2") 134 | TooltipPanel/styles/panel = SubResource("8") 135 | -------------------------------------------------------------------------------- /gdsbin/parsertree.gd: -------------------------------------------------------------------------------- 1 | class_name Parsertree 2 | 3 | ## GDScript Transpiler Properties Class 4 | ## 5 | ## Properties for Transpiler 6 | ## 7 | 8 | ## Method to process input string and list of tokens 9 | 10 | func printtree(element, level: int) -> Dictionary: 11 | match element.get_script().get_global_name(): 12 | "Root": 13 | var dictionary: Dictionary = {} 14 | if element.elem.size() > 0: 15 | for i in range (0, element.elem.size()): 16 | dictionary["Root" + str(i)] = printtree(element.elem[i], level) 17 | return dictionary 18 | "Comment": 19 | return {"Comment": {element.comment: null}} 20 | "Classn": 21 | return {"class_name": {element.classn: null}} 22 | "Extend": 23 | return {"extends": {element.extend: null}} 24 | "Function": 25 | return {"Function": null} 26 | "Variable": 27 | return {"Variable": {element.variable: null}} 28 | "Forloop": 29 | return {"Forloop": null} 30 | "Ifcond": 31 | return {"Ifconf": null} 32 | "Callnew": 33 | return {"Callnew": null} 34 | return {"": null} 35 | 36 | func printpt(element, level: int) -> String: 37 | match element.get_script().get_global_name(): 38 | "Root": 39 | var out: String = "" 40 | if element.elem.size() > 0: 41 | for e in element.elem: 42 | for i in range(level): 43 | out += " " 44 | out += printpt(e, level) 45 | return out 46 | "Comment": 47 | return element.comment + "\n" 48 | "Classn": 49 | return "class_name " + element.classn + "\n" 50 | "Extend": 51 | return "extends " + element.extend + "\n" 52 | "Function": 53 | var out: String = "" 54 | out += "func " + element.function + "(" 55 | var s = element.args.size() 56 | if s!=0: 57 | for i in range(0, s-1, 1): 58 | out += eval_call(element.args[i]) + ", " 59 | out += eval_call(element.args[s-1]) 60 | out += ")" 61 | if element.ret: 62 | out += " -> " 63 | out += element.res 64 | out += ":" 65 | out += "\n" 66 | if (element.root != null): 67 | out += printpt(element.root, level+1) 68 | return out 69 | "Variable": 70 | var out = "var" 71 | if element.is_const: 72 | out = "const" 73 | out += " " + element.variable 74 | if element.st: 75 | out += ": " 76 | if element.type != "": 77 | out += element.type 78 | if element.equ: 79 | out += " = " 80 | out += eval_call(element.res) 81 | return out + "\n" 82 | "Forloop": 83 | var out = "for" 84 | out += " " + parse_call(element.f) 85 | out += " " + "in" 86 | out += " " + parse_call(element.i) 87 | out += ":" 88 | out += "\n" 89 | if (element.root != null): 90 | out += printpt(element.root, level+1) 91 | return out 92 | "Ifcond": 93 | var out = "i" 94 | out += "f" 95 | out += " " + parse_call(element.i) 96 | out += ":" 97 | out += "\n" 98 | if (element.root != null): 99 | out += printpt(element.root, level+1) 100 | return out 101 | "Callnew": 102 | return parse_call(element) + "\n" 103 | return "" 104 | 105 | func eval_call(element): 106 | var out: String = "" 107 | if element != null: 108 | if element.get_script().get_global_name() == "Stringname": 109 | out += element.string 110 | elif element.get_script().get_global_name() == "Dictionaryname": 111 | out += "{}" 112 | elif element.get_script().get_global_name() == "Callnew": 113 | if element.builtin_function: 114 | out += element.name.to_lower() 115 | else: 116 | out += element.name 117 | if element.function: 118 | out += "(" 119 | var s = element.args.size() 120 | if s!=0: 121 | for i in range(0, s-1, 1): 122 | out += eval_call(element.args[i]) + ", " 123 | out += eval_call(element.args[s-1]) 124 | out += ")" 125 | while (element.callnew != null): 126 | element = element.callnew 127 | out += "." 128 | if element.builtin_function: 129 | out += element.name.to_lower() 130 | else: 131 | out += element.name 132 | if element.function: 133 | out += "(" 134 | var s = element.args.size() 135 | if s!=0: 136 | for i in range(0, s-1, 1): 137 | out += eval_call(element.args[i]) 138 | out += ", " 139 | out += eval_call(element.args[s-1]) 140 | out += ")" 141 | else: 142 | out += str(element).replace(" ", "") 143 | return out 144 | 145 | func parse_call(element): 146 | var out = "" 147 | if element.builtin_function: 148 | out += element.name.to_lower() 149 | else: 150 | out += element.name 151 | if element.function: 152 | out += "(" 153 | var s = element.args.size() 154 | if s!=0: 155 | for i in range(0, s-1, 1): 156 | out += eval_call(element.args[i]) + ", " 157 | out += eval_call(element.args[s-1]) 158 | out += ")" 159 | while (element.callnew != null): 160 | element = element.callnew 161 | out += "." 162 | if element.builtin_function: 163 | out += element.name.to_lower() 164 | else: 165 | out += element.name 166 | if element.function: 167 | out += "(" 168 | var s = element.args.size() 169 | if s!=0: 170 | for i in range(0, s-1, 1): 171 | out += eval_call(element.args[i]) 172 | out += ", " 173 | out += eval_call(element.args[s-1]) 174 | out += ")" 175 | if element.equ: 176 | if element.op == "": 177 | out += " = " 178 | elif element.op == "PLUS": 179 | out += " += " 180 | elif element.op == "MINUS": 181 | out += " -= " 182 | elif element.op == "ASTERISK": 183 | out += " *= " 184 | elif element.op == "SLASH": 185 | out += " /= " 186 | out += eval_call(element.res) 187 | return out 188 | 189 | func printrec(e: Dictionary, ch: String) -> String: 190 | var s: String = "" 191 | var k: Array = e.keys() 192 | var i: int = k.size() - 1 193 | for item in k: 194 | s += ch 195 | s += ("├─" if i != 0 else "└─" if ch != "" else "──") 196 | s += ("┐ " if e[item] != null else " ") 197 | s += item 198 | s += "\n" 199 | if e[item] != null: 200 | s += printrec(e[item], ch + ("│ " if i != 0 else " ")) 201 | i -= 1 202 | return s 203 | -------------------------------------------------------------------------------- /gdsbin/key.gd: -------------------------------------------------------------------------------- 1 | ## GDScript Transpiler Properties Class 2 | 3 | # Autogenerated class (gen_api) 4 | # See https://raw.githubusercontent.com/godotengine/godot-cpp/master/gdextension/extension_api.json 5 | 6 | class_name Key 7 | 8 | const KEY_NONE: int = 0 9 | const KEY_SPECIAL: int = 4194304 10 | const KEY_ESCAPE: int = 4194305 11 | const KEY_TAB: int = 4194306 12 | const KEY_BACKTAB: int = 4194307 13 | const KEY_BACKSPACE: int = 4194308 14 | const KEY_ENTER: int = 4194309 15 | const KEY_KP_ENTER: int = 4194310 16 | const KEY_INSERT: int = 4194311 17 | const KEY_DELETE: int = 4194312 18 | const KEY_PAUSE: int = 4194313 19 | const KEY_PRINT: int = 4194314 20 | const KEY_SYSREQ: int = 4194315 21 | const KEY_CLEAR: int = 4194316 22 | const KEY_HOME: int = 4194317 23 | const KEY_END: int = 4194318 24 | const KEY_LEFT: int = 4194319 25 | const KEY_UP: int = 4194320 26 | const KEY_RIGHT: int = 4194321 27 | const KEY_DOWN: int = 4194322 28 | const KEY_PAGEUP: int = 4194323 29 | const KEY_PAGEDOWN: int = 4194324 30 | const KEY_SHIFT: int = 4194325 31 | const KEY_CTRL: int = 4194326 32 | const KEY_META: int = 4194327 33 | const KEY_ALT: int = 4194328 34 | const KEY_CAPSLOCK: int = 4194329 35 | const KEY_NUMLOCK: int = 4194330 36 | const KEY_SCROLLLOCK: int = 4194331 37 | const KEY_F1: int = 4194332 38 | const KEY_F2: int = 4194333 39 | const KEY_F3: int = 4194334 40 | const KEY_F4: int = 4194335 41 | const KEY_F5: int = 4194336 42 | const KEY_F6: int = 4194337 43 | const KEY_F7: int = 4194338 44 | const KEY_F8: int = 4194339 45 | const KEY_F9: int = 4194340 46 | const KEY_F10: int = 4194341 47 | const KEY_F11: int = 4194342 48 | const KEY_F12: int = 4194343 49 | const KEY_F13: int = 4194344 50 | const KEY_F14: int = 4194345 51 | const KEY_F15: int = 4194346 52 | const KEY_F16: int = 4194347 53 | const KEY_F17: int = 4194348 54 | const KEY_F18: int = 4194349 55 | const KEY_F19: int = 4194350 56 | const KEY_F20: int = 4194351 57 | const KEY_F21: int = 4194352 58 | const KEY_F22: int = 4194353 59 | const KEY_F23: int = 4194354 60 | const KEY_F24: int = 4194355 61 | const KEY_F25: int = 4194356 62 | const KEY_F26: int = 4194357 63 | const KEY_F27: int = 4194358 64 | const KEY_F28: int = 4194359 65 | const KEY_F29: int = 4194360 66 | const KEY_F30: int = 4194361 67 | const KEY_F31: int = 4194362 68 | const KEY_F32: int = 4194363 69 | const KEY_F33: int = 4194364 70 | const KEY_F34: int = 4194365 71 | const KEY_F35: int = 4194366 72 | const KEY_KP_MULTIPLY: int = 4194433 73 | const KEY_KP_DIVIDE: int = 4194434 74 | const KEY_KP_SUBTRACT: int = 4194435 75 | const KEY_KP_PERIOD: int = 4194436 76 | const KEY_KP_ADD: int = 4194437 77 | const KEY_KP_0: int = 4194438 78 | const KEY_KP_1: int = 4194439 79 | const KEY_KP_2: int = 4194440 80 | const KEY_KP_3: int = 4194441 81 | const KEY_KP_4: int = 4194442 82 | const KEY_KP_5: int = 4194443 83 | const KEY_KP_6: int = 4194444 84 | const KEY_KP_7: int = 4194445 85 | const KEY_KP_8: int = 4194446 86 | const KEY_KP_9: int = 4194447 87 | const KEY_MENU: int = 4194370 88 | const KEY_HYPER: int = 4194371 89 | const KEY_HELP: int = 4194373 90 | const KEY_BACK: int = 4194376 91 | const KEY_FORWARD: int = 4194377 92 | const KEY_STOP: int = 4194378 93 | const KEY_REFRESH: int = 4194379 94 | const KEY_VOLUMEDOWN: int = 4194380 95 | const KEY_VOLUMEMUTE: int = 4194381 96 | const KEY_VOLUMEUP: int = 4194382 97 | const KEY_MEDIAPLAY: int = 4194388 98 | const KEY_MEDIASTOP: int = 4194389 99 | const KEY_MEDIAPREVIOUS: int = 4194390 100 | const KEY_MEDIANEXT: int = 4194391 101 | const KEY_MEDIARECORD: int = 4194392 102 | const KEY_HOMEPAGE: int = 4194393 103 | const KEY_FAVORITES: int = 4194394 104 | const KEY_SEARCH: int = 4194395 105 | const KEY_STANDBY: int = 4194396 106 | const KEY_OPENURL: int = 4194397 107 | const KEY_LAUNCHMAIL: int = 4194398 108 | const KEY_LAUNCHMEDIA: int = 4194399 109 | const KEY_LAUNCH0: int = 4194400 110 | const KEY_LAUNCH1: int = 4194401 111 | const KEY_LAUNCH2: int = 4194402 112 | const KEY_LAUNCH3: int = 4194403 113 | const KEY_LAUNCH4: int = 4194404 114 | const KEY_LAUNCH5: int = 4194405 115 | const KEY_LAUNCH6: int = 4194406 116 | const KEY_LAUNCH7: int = 4194407 117 | const KEY_LAUNCH8: int = 4194408 118 | const KEY_LAUNCH9: int = 4194409 119 | const KEY_LAUNCHA: int = 4194410 120 | const KEY_LAUNCHB: int = 4194411 121 | const KEY_LAUNCHC: int = 4194412 122 | const KEY_LAUNCHD: int = 4194413 123 | const KEY_LAUNCHE: int = 4194414 124 | const KEY_LAUNCHF: int = 4194415 125 | const KEY_GLOBE: int = 4194416 126 | const KEY_KEYBOARD: int = 4194417 127 | const KEY_JIS_EISU: int = 4194418 128 | const KEY_JIS_KANA: int = 4194419 129 | const KEY_UNKNOWN: int = 8388607 130 | const KEY_SPACE: int = 32 131 | const KEY_EXCLAM: int = 33 132 | const KEY_QUOTEDBL: int = 34 133 | const KEY_NUMBERSIGN: int = 35 134 | const KEY_DOLLAR: int = 36 135 | const KEY_PERCENT: int = 37 136 | const KEY_AMPERSAND: int = 38 137 | const KEY_APOSTROPHE: int = 39 138 | const KEY_PARENLEFT: int = 40 139 | const KEY_PARENRIGHT: int = 41 140 | const KEY_ASTERISK: int = 42 141 | const KEY_PLUS: int = 43 142 | const KEY_COMMA: int = 44 143 | const KEY_MINUS: int = 45 144 | const KEY_PERIOD: int = 46 145 | const KEY_SLASH: int = 47 146 | const KEY_0: int = 48 147 | const KEY_1: int = 49 148 | const KEY_2: int = 50 149 | const KEY_3: int = 51 150 | const KEY_4: int = 52 151 | const KEY_5: int = 53 152 | const KEY_6: int = 54 153 | const KEY_7: int = 55 154 | const KEY_8: int = 56 155 | const KEY_9: int = 57 156 | const KEY_COLON: int = 58 157 | const KEY_SEMICOLON: int = 59 158 | const KEY_LESS: int = 60 159 | const KEY_EQUAL: int = 61 160 | const KEY_GREATER: int = 62 161 | const KEY_QUESTION: int = 63 162 | const KEY_AT: int = 64 163 | const KEY_A: int = 65 164 | const KEY_B: int = 66 165 | const KEY_C: int = 67 166 | const KEY_D: int = 68 167 | const KEY_E: int = 69 168 | const KEY_F: int = 70 169 | const KEY_G: int = 71 170 | const KEY_H: int = 72 171 | const KEY_I: int = 73 172 | const KEY_J: int = 74 173 | const KEY_K: int = 75 174 | const KEY_L: int = 76 175 | const KEY_M: int = 77 176 | const KEY_N: int = 78 177 | const KEY_O: int = 79 178 | const KEY_P: int = 80 179 | const KEY_Q: int = 81 180 | const KEY_R: int = 82 181 | const KEY_S: int = 83 182 | const KEY_T: int = 84 183 | const KEY_U: int = 85 184 | const KEY_V: int = 86 185 | const KEY_W: int = 87 186 | const KEY_X: int = 88 187 | const KEY_Y: int = 89 188 | const KEY_Z: int = 90 189 | const KEY_BRACKETLEFT: int = 91 190 | const KEY_BACKSLASH: int = 92 191 | const KEY_BRACKETRIGHT: int = 93 192 | const KEY_ASCIICIRCUM: int = 94 193 | const KEY_UNDERSCORE: int = 95 194 | const KEY_QUOTELEFT: int = 96 195 | const KEY_BRACELEFT: int = 123 196 | const KEY_BAR: int = 124 197 | const KEY_BRACERIGHT: int = 125 198 | const KEY_ASCIITILDE: int = 126 199 | const KEY_YEN: int = 165 200 | const KEY_SECTION: int = 167 201 | -------------------------------------------------------------------------------- /gdsbin/vector2.gd: -------------------------------------------------------------------------------- 1 | class_name VECTOR2 2 | 3 | var x : float = 0 4 | var y : float = 0 5 | 6 | ## Returns this vector's angle with respect to the positive X axis, or (1, 0) vector, in radians. 7 | func angle(v) -> float: 8 | return atan2(v.y, v.x) 9 | 10 | 11 | func from_angle(p_angle : float): 12 | var vector2 = VECTOR2.new() 13 | vector2.x = sin(p_angle) 14 | vector2.y = cos(p_angle) 15 | return vector2 16 | 17 | 18 | ## Returns the length (magnitude) of this vector. 19 | func vec_length(v) -> float: 20 | return sqrt(length_squared(v)) 21 | 22 | 23 | ## Returns the squared length (squared magnitude) of this vector. 24 | func length_squared(v) -> float: 25 | return v.x * v.x + v.y * v.y 26 | 27 | 28 | ## Returns the vector scaled to unit length. Equivalent to v / v.length(). 29 | func normalized(v): 30 | var vector2 = VECTOR2.new() 31 | var l : float = v.x * v.x + v.y * v.y 32 | if (l != 0): 33 | l = sqrt(l) 34 | vector2.x = v.x/l 35 | vector2.y = v.y/l 36 | return vector2 37 | vector2.x = v.x 38 | vector2.y = v.y 39 | return vector2 40 | 41 | 42 | ## Returns true if the vector is normalized, false otherwise. 43 | func is_normalized(v) -> bool: 44 | return math_is_equal_approx(length_squared(v), 1) 45 | 46 | 47 | ## Returns the distance between this vector and to. 48 | func distance_to(p_vector2, v) -> float: 49 | return sqrt((v.x - p_vector2.x) * (v.x - p_vector2.x) + (v.y - p_vector2.y) * (v.y - p_vector2.y)) 50 | 51 | 52 | ## Returns the squared distance between this vector and b. 53 | func distance_squared_to(p_vector2, v) -> float: 54 | return (v.x - p_vector2.x) * (v.x - p_vector2.x) + (v.y - p_vector2.y) * (v.y - p_vector2.y) 55 | 56 | 57 | ## Returns the angle to the given vector, in radians. 58 | func angle_to(vector2, p_vector2) -> float: 59 | return atan2(cross(vector2, p_vector2), dot(vector2, p_vector2)) 60 | 61 | 62 | ## Returns the angle between the line connecting the two points and the X axis, in radians. 63 | func angle_to_point(vector2, p_vector2) -> float: 64 | return angle(sub(vector2, p_vector2)) 65 | 66 | 67 | ## Returns the dot product of this vector and with. This can be used to compare the angle between two vectors. 68 | func dot(vector2, p_other) -> float: 69 | return vector2.x * p_other.x + vector2.y * p_other.y 70 | 71 | 72 | ## Returns the 2D analog of the cross product for this vector and with. 73 | func cross(vector2, p_other) -> float: 74 | return vector2.x * p_other.y - vector2.y * p_other.x 75 | 76 | 77 | ## Returns a new vector with each component set to one or negative one, depending on the signs of the components. 78 | func sign(v): 79 | var sign: VECTOR2 = self 80 | sign.x = sign(v.x) 81 | sign.y = sign(v.y) 82 | return sign 83 | 84 | 85 | ## Returns a new vector with all components rounded down (towards negative infinity). 86 | func floor(v): 87 | var floor: VECTOR2 = self 88 | floor.x = floor(v.x) 89 | floor.y = floor(v.y) 90 | return floor 91 | 92 | 93 | ## Returns a new vector with all components rounded up (towards positive infinity). 94 | func ceil(v): 95 | var ceil: VECTOR2 = self 96 | ceil.x = ceil(v.x) 97 | ceil.y = ceil(v.y) 98 | return ceil 99 | 100 | 101 | ## Returns a new vector with all components rounded to the nearest integer, with halfway cases rounded away from zero. 102 | func round(v): 103 | var round: VECTOR2 = self 104 | round.x = round(v.x) 105 | round.y = round(v.y) 106 | return round 107 | 108 | 109 | ## Returns the vector rotated by angle (in radians). 110 | func rotated(vec2, p_by : float): 111 | var sine : float = sin(p_by) 112 | var cosi : float = cos(p_by) 113 | var vector2 = VECTOR2.new() 114 | vector2.x = vec2.x * cosi - vec2.y * sine 115 | vector2.y = vec2.x * sine + vec2.y * cosi 116 | return vector2 117 | 118 | 119 | ## Returns a vector composed of the fposmod of this vector's components and mod. 120 | func posmod(vec2, p_mod: float): 121 | var vector2 = VECTOR2.new() 122 | vector2.x = fposmod(vec2.x, p_mod) 123 | vector2.y = fposmod(vec2.y, p_mod) 124 | return vector2 125 | 126 | 127 | ## Returns a vector composed of the fposmod of this vector's components and modv's components. 128 | func posmodv(vec2, p_modv): 129 | var vector2 = VECTOR2.new() 130 | vector2.x = fposmod(vec2.x, p_modv.x) 131 | vector2.y = fposmod(vec2.y, p_modv.y) 132 | return vector2 133 | 134 | 135 | ## Returns this vector projected onto the vector b. 136 | func project(vector2, p_to): 137 | return mul(p_to, dot(vector2, p_to) / p_to.length_squared(p_to)) 138 | 139 | 140 | 141 | ## Deprecated, please use limit_length instead. 142 | func clamped(vec2, p_min, p_max): 143 | var vector2 = VECTOR2.new() 144 | vector2.x = clamp(vec2.x, p_min.x, p_max.x) 145 | vector2.y = clamp(vec2.y, p_min.y, p_max.y) 146 | return vector2 147 | 148 | 149 | ## Returns this vector with each component snapped to the nearest multiple of step. This can also be used to round to an arbitrary number of decimals. 150 | func snapped(vec2, p_step): 151 | var vector2 = VECTOR2.new() 152 | vector2.x = snapped(vec2.x, p_step.x) 153 | vector2.y = snapped(vec2.y, p_step.y) 154 | return vector2 155 | 156 | 157 | ## Returns the vector with a maximum length by limiting its length to length. 158 | func limit_length(vec2, p_len : float, v1): 159 | var l : float = vec_length(v1) 160 | var v = vec2 161 | if (l > 0 && p_len < l): 162 | return mul(div(v, l), p_len) 163 | return v 164 | 165 | 166 | ## Returns a new vector moved toward to by the fixed delta amount. Will not go past the final value. 167 | func move_toward(vec2, p_to, p_delta : float): 168 | var v = vec2 169 | var vd = p_to.sub(v) 170 | var len : float = vd.vec_length() 171 | if (len <= p_delta): 172 | return p_to 173 | else: 174 | return add(v, mul(vd.div(len), p_delta)) 175 | 176 | 177 | ## Returns this vector slid along a plane defined by the given normal. 178 | func slide(vector2, p_normal): 179 | return sub(vector2, mul(p_normal, dot(vector2, p_normal))) 180 | 181 | 182 | ## Returns the vector "bounced off" from a plane defined by the given normal. 183 | func bounce(vector2, p_normal): 184 | return inv(reflect(vector2, p_normal)) 185 | 186 | 187 | ## Returns the vector reflected (i.e. mirrored, or symmetric) over a line defined by the given direction vector n. 188 | func reflect(vector2, p_normal): 189 | return sub(mul(mul(p_normal, 2.0), dot(vector2, p_normal)), vector2) 190 | 191 | 192 | ## Returns true if this vector and v are approximately equal, by running math_is_equal_approx on each component. 193 | func vec_is_equal_approx(p_v, v) -> bool: 194 | return math_is_equal_approx(v.x, p_v.x) and math_is_equal_approx(v.y, p_v.y) 195 | 196 | 197 | ## Returns true if this vector is approximately zero, by running is_zero_approx on each component. 198 | func is_zero_approx(v) -> bool: 199 | return is_zero_approx(v.x) and is_zero_approx(v.y) 200 | 201 | 202 | ## Returns true if this vector is finite, by running is_finite on each component. 203 | func is_finite(v) -> bool: 204 | return is_finite(v.x) and is_finite(v.y) 205 | 206 | 207 | func sub(vec1, vec2): 208 | var vector2 = VECTOR2.new() 209 | vector2.x = vec1.x-vec2.x 210 | vector2.y = vec1.y-vec2.y 211 | return vector2 212 | 213 | 214 | func add(vec1, vec2): 215 | var vector2 = VECTOR2.new() 216 | vector2.x = vec1.x+vec2.x 217 | vector2.y = vec1.y+vec2.y 218 | return vector2 219 | 220 | 221 | func mul(vec, p_by : float): 222 | var vector2 = VECTOR2.new() 223 | vector2.x = vec.x*p_by 224 | vector2.y = vec.y*p_by 225 | return vector2 226 | 227 | 228 | func inv(vec): 229 | var vector2 = VECTOR2.new() 230 | vector2.x = -vec.x 231 | vector2.y = -vec.y 232 | return vector2 233 | 234 | 235 | func div(vec, p_by : float): 236 | var vector2 = VECTOR2.new() 237 | vector2.x = vec.x/p_by 238 | vector2.y = vec.y/p_by 239 | return vector2 240 | 241 | 242 | func math_is_equal_approx(a : float, b : float) -> bool: 243 | # Check for exact equality first, required to handle "infinity" values. 244 | if (a == b): 245 | return true 246 | var CMP_EPSILON : float = 0.00001 247 | var tolerance : float = CMP_EPSILON * abs(a) 248 | if tolerance < CMP_EPSILON: 249 | tolerance = CMP_EPSILON 250 | return abs(a-b) < tolerance 251 | -------------------------------------------------------------------------------- /gdsbin/script_editor.gd: -------------------------------------------------------------------------------- 1 | # Copyright © 2019-2022 Hugo Locurcio and contributors - MIT License 2 | # See `LICENSE.md` included in the source distribution for details. 3 | extends TextEdit 4 | 5 | @onready var error_label: Label = $"/root/MainWindow/HSplitContainer/ok/OutputPanel/ErrorLabel" 6 | @onready var output_panel: RichTextLabel = $"/root/MainWindow/HSplitContainer/ok/OutputPanel/RichTextLabel" 7 | var ch : CodeHighlighter = self.syntax_highlighter 8 | var _main = Transpiler.new() 9 | 10 | # The printing functions to create. 11 | const PRINT_FUNCS = { 12 | "print": "", # Nothing between arguments, newline at end. 13 | "prints": " ", # Space between arguments, newline at end. 14 | "printt": "\\t", # Tab between arguments, newline at end. 15 | "printraw": "", # Nothing between arguments, no newline at end. 16 | } 17 | 18 | # Functions to replace in the script that will be run (see above). 19 | const FUNC_REPLACEMENTS = { 20 | "print(": "self.print(", 21 | "print (": "self.print (", 22 | "prints(": "self.prints(", 23 | "prints (": "self.prints (", 24 | "printt(": "self.printt(", 25 | "printt (": "self.prints (", 26 | "printraw(": "self.printraw(", 27 | "printraw (": "self.printraw (", 28 | } 29 | 30 | # Taken from the Default (Godot 2.x-like) script editor theme. 31 | # https://github.com/godotengine/godot/blob/4ea73633047e5b52dee38ffe0b958f60e859d5b7/editor/editor_settings.cpp#L785-L822 32 | const KEYWORD_COLOR := Color(1.0, 1.0, 0.7) 33 | # More orange to be easier to distinguish. 34 | const CONTROL_FLOW_KEYWORD_COLOR := Color(1.0, 0.7, 0.7) 35 | const BASE_TYPE_COLOR := Color(0.64, 1.0, 0.83) 36 | const ENGINE_TYPE_COLOR := Color(0.51, 0.83, 1.0) 37 | const STRING_COLOR := Color(0.94, 0.43, 0.75) 38 | # Slightly brighter than the default theme to improve readability. 39 | const COMMENT_COLOR := Color(0.45, 0.45, 0.45) 40 | 41 | # All reserved words in GDScript, minus control flow keywords (for syntax highlighting). 42 | const KEYWORDS := [ 43 | # Operators. 44 | "and", 45 | "in", 46 | "not", 47 | "or", 48 | # Types and values. 49 | "false", 50 | "float", 51 | "int", 52 | "bool", 53 | "null", 54 | "PI", 55 | "TAU", 56 | "INF", 57 | "NAN", 58 | "self", 59 | "true", 60 | "void", 61 | # Functions. 62 | "as", 63 | "assert", 64 | "await", 65 | "breakpoint", 66 | "class", 67 | "class_name", 68 | "extends", 69 | "is", 70 | "func", 71 | "preload", 72 | "signal", 73 | "super", 74 | "trait", 75 | "yield", 76 | # Variables. 77 | "const", 78 | "enum", 79 | "static", 80 | "var", 81 | ] 82 | 83 | # Control flow keywords (for syntax highlighting). 84 | const CONTROL_FLOW_KEYWORDS = [ 85 | "break", 86 | "continue", 87 | "if", 88 | "elif", 89 | "else", 90 | "for", 91 | "pass", 92 | "return", 93 | "match", 94 | "while", 95 | ] 96 | 97 | # All base types in Godot (for syntax highlighting). 98 | const BASE_TYPES = [ 99 | "null", 100 | "String", 101 | "Vector2", 102 | "Rect2", 103 | "Vector3", 104 | "Transform2D", 105 | "Plane", 106 | "Quat", 107 | "AABB", 108 | "Basis", 109 | "Transform", 110 | "Color", 111 | "NodePath", 112 | "RID", 113 | "Object", 114 | "Dictionary", 115 | "Array", 116 | "PoolByteArray", 117 | "PoolIntArray", 118 | "PoolRealArray", 119 | "PoolStringArray", 120 | "PoolVector2Array", 121 | "PoolVector3Array", 122 | "PoolColorArray", 123 | ] 124 | 125 | # Implement `print()` functions in the script for use with the output panel. 126 | # This must be done because built-in `print()` functions' output cannot be redirected. 127 | var print_func_template := """ 128 | func {name}(arg1 = '', arg2 = '', arg3 = '', arg4 = '', arg5 = '', arg6 = '', arg7 = '', arg8 = '', arg9 = '') -> void: 129 | # Also call the built-in printing function 130 | {name}(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) 131 | 132 | var text := '' 133 | for argument in [arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9]: 134 | text += str(argument) + '{separator}' 135 | 136 | text += '{end_separator}' 137 | 138 | {output_panel}.add_text(text) 139 | """.format({ 140 | output_panel = "$'/root/MainWindow/HSplitContainer/ok/OutputPanel/RichTextLabel'" 141 | }) 142 | 143 | # The script shim that will be inserted at the end of the user-provided script. 144 | var script_shim := "" 145 | 146 | var package_name: String = "" 147 | 148 | func _ready() -> void: 149 | var __init__ = preload("__init__.gd").new() 150 | package_name = __init__.package_name 151 | transpile(package_name) 152 | # Add in the missing bits of syntax highlighting for GDScript. 153 | for keyword in KEYWORDS: 154 | ch.add_keyword_color(keyword, KEYWORD_COLOR) 155 | 156 | for keyword in CONTROL_FLOW_KEYWORDS: 157 | ch.add_keyword_color(keyword, CONTROL_FLOW_KEYWORD_COLOR) 158 | 159 | for base_type in BASE_TYPES: 160 | ch.add_keyword_color(base_type, BASE_TYPE_COLOR) 161 | 162 | for engine_type in ClassDB.get_class_list(): 163 | ch.add_keyword_color(engine_type, ENGINE_TYPE_COLOR) 164 | 165 | ch.add_color_region('"', '"', STRING_COLOR, false) 166 | ch.add_color_region("'", "'", STRING_COLOR, false) 167 | ch.add_color_region("#", "", COMMENT_COLOR, false) 168 | 169 | # Generate printing functions 170 | for print_func in PRINT_FUNCS: 171 | script_shim += print_func_template.format({ 172 | name = print_func, 173 | separator = PRINT_FUNCS[print_func], 174 | end_separator = "" if print_func == "printraw" else "\\n", 175 | }) 176 | 177 | 178 | func _run_button_pressed() -> void: 179 | # Clear the Output panel. 180 | output_panel.text = "" 181 | 182 | # Replace `print()` and similar functions with our own so that messages 183 | # can be displayed in the output panel. 184 | var script_text := text 185 | for func_replacement in FUNC_REPLACEMENTS: 186 | script_text = script_text.replace( 187 | func_replacement, 188 | FUNC_REPLACEMENTS[func_replacement] 189 | ) 190 | 191 | # Append the script shim and load the script. 192 | script_text += script_shim 193 | var script := GDScript.new() 194 | script.source_code = script_text 195 | var error := script.reload() 196 | 197 | # Display an error message if the script parsing failed. 198 | error_label.text = "Parser error in the script (invalid syntax).\nCheck browser console for more information." if error != OK else "" 199 | if error == OK: 200 | var run_context: Object = script.new() 201 | # Instance the script so it can access the scene tree. 202 | # This also runs the script's `_init()` and `_ready()` functions. 203 | get_tree().get_root().add_child(run_context) 204 | # Clean up once the script is done running. 205 | run_context.queue_free() 206 | func _gui_input(event: InputEvent) -> void: 207 | if event.is_action_pressed("toggle_comment") && self.editable: 208 | # If no selection is active, toggle comment on the line the cursor is currently on. 209 | var from 210 | var to 211 | if has_selection(): 212 | from = get_selection_from_line() 213 | to = get_selection_to_line() 214 | else: 215 | from = get_caret_line() 216 | to = get_caret_line() 217 | for line in range(from, to + 1): 218 | if not get_line(line).begins_with("#"): 219 | # Code is already commented out at the beginning of the line. Uncomment it. 220 | set_line(line, "#%s" % get_line(line)) 221 | else: 222 | # Code isn't commented out at the beginning of the line. Comment it. 223 | set_line(line, get_line(line).substr(1)) 224 | elif event.is_action_pressed("tab") && self.editable: 225 | # If no selection is active, toggle comment on the line the cursor is currently on. 226 | var from 227 | var to 228 | if has_selection(): 229 | from = get_selection_from_line() 230 | to = get_selection_to_line() 231 | else: 232 | from = get_caret_line() 233 | to = get_caret_line() 234 | for line in range(from, to + 1): 235 | set_line(line, " %s" % get_line(line)) 236 | set_caret_column(get_caret_column()+1) 237 | 238 | 239 | func transpile(pkg_name: String): 240 | $/root/MainWindow/HSplitContainer/ok/VBoxContainer2/ScriptEditor.set_text(_main.transpile($/root/MainWindow/HSplitContainer/VBoxContainer/ScriptEditor.get_text(), pkg_name)) 241 | 242 | 243 | func _on_run_button_2_pressed(): 244 | var stdout: Array = [] 245 | var msg = $/root/MainWindow/HSplitContainer/ok/VBoxContainer2/ScriptEditor.get_text().replace("'", "\\'").replace('"', '\\"') 246 | var exit = OS.execute('python3.13',['-c',msg],stdout,true,false) 247 | var output : String = "" 248 | output_panel.set_text(output) 249 | error_label.set_text(output) 250 | for line in stdout: 251 | output += line 252 | output += "\n" 253 | stdout.clear() 254 | if exit == OK: 255 | output_panel.set_text(output) 256 | else: 257 | error_label.set_text(output) 258 | 259 | 260 | 261 | func _on_script_editor_text_changed(): 262 | transpile(package_name) 263 | -------------------------------------------------------------------------------- /gdsbin/ast.gd: -------------------------------------------------------------------------------- 1 | class_name Ast 2 | 3 | ## GDScript Transpiler Properties Class 4 | ## 5 | ## Properties for Transpiler 6 | ## 7 | ## Method to process input string and list of tokens 8 | 9 | var key = Key.new() 10 | var keyword = Keyword.new() 11 | 12 | func ast(startln: int, endln: int, level: int, root, unit: Array, con: Array): 13 | for i in range(startln, endln, 1): 14 | var input = unit[i] 15 | var conline = con[i] 16 | if input.size() < level+1: 17 | continue 18 | var tabcount: int = 0 19 | for ii in range(0, input.size(), 1): 20 | if input[ii].id == key.KEY_TAB: 21 | tabcount += 1 22 | else: 23 | break 24 | if tabcount > level: 25 | continue 26 | elif tabcount < level: 27 | break 28 | if root == null: 29 | root = Root.new() 30 | root.elem = [] 31 | if input[level].id == key.KEY_NUMBERSIGN: 32 | _number_sign(root, conline, level) 33 | continue 34 | if input[level].id == keyword.KW_NUMBERSIGN2: 35 | _number_sign(root, conline, level) 36 | continue 37 | if input[level].id == keyword.KW_CLASSNAME: 38 | _classname(root, input, level) 39 | continue 40 | if input[level].id == keyword.KW_EXTENDS: 41 | _extend(root, input, level) 42 | continue 43 | if input[level].id == keyword.KW_FUNCTION: 44 | _function(i, endln, level, root, input, unit, con) 45 | continue 46 | if input[level].id == keyword.KW_FOR: 47 | _for_in(i, endln, level, root, input, unit, con) 48 | continue 49 | if input[level].id == keyword.KW_IF: 50 | _if_cond(i, endln, level, root, input, unit, con) 51 | continue 52 | if input[level].id == keyword.KW_VARIABLE: 53 | const is_const: bool = false 54 | _variable(root, input, level, is_const) 55 | continue 56 | if input[level].id == keyword.KW_CONST: 57 | const is_const: bool = true 58 | _variable(root, input, level, is_const) 59 | continue 60 | _call(root, input, level) 61 | return root 62 | 63 | func _number_sign(root, conline: String, level: int): 64 | var comment = Comment.new() 65 | comment.comment = _cut_string(conline, level) 66 | root.elem.append(comment) 67 | #print(input) 68 | 69 | func _number_sign_2(root, conline: String, level: int): 70 | var comment = Comment.new() 71 | comment.comment = _cut_string(conline, level) 72 | root.elem.append(comment) 73 | #print(input) 74 | 75 | func _classname(root, input: Array, level: int): 76 | var classn = Classn.new() 77 | classn.classn = input[level+1].value 78 | root.elem.append(classn) 79 | #print(input) 80 | 81 | func _extend(root, input: Array, level: int): 82 | var extend = Extend.new() 83 | extend.extend = input[level+1].value 84 | root.elem.append(extend) 85 | #print(input) 86 | 87 | func _call(root, input: Array, level: int): 88 | var callx = _new_call(input, level) 89 | root.elem.append(callx) 90 | #print(input) 91 | 92 | func _arg_call(input: Array, level: int): 93 | var callnew = Callnew.new() 94 | var s = input.size() 95 | if level+1 < s: 96 | if input[level+1].id == key.KEY_PERIOD: 97 | callnew.name = input[level].value 98 | callnew.callnew = _new_call(input, level+2) 99 | elif input.size() > 2: 100 | callnew.name = _eval_string(input, 0).string 101 | else: 102 | callnew.name = input[level].value 103 | return callnew 104 | 105 | func _new_call(input: Array, level: int): 106 | var callnew = Callnew.new() 107 | var s = input.size() 108 | if level+1 < s: 109 | if input[level+1].id == key.KEY_PERIOD: 110 | callnew.name = input[level].value 111 | callnew.callnew = _new_call(input, level+2) 112 | elif input[level+1].id == key.KEY_EQUAL: 113 | callnew.name = input[level].value 114 | callnew.equ = true 115 | var array: Array = [] 116 | for i in range(level+2, input.size()): 117 | array.append(input[i]) 118 | callnew.res = _eval(array) 119 | elif input[level+1].id in [key.KEY_PLUS, key.KEY_MINUS, key.KEY_ASTERISK, key.KEY_SLASH]: 120 | callnew.name = input[level].value 121 | callnew.equ = true 122 | callnew.op = input[level+1].value 123 | var array: Array = [] 124 | for i in range(level+2, input.size()): 125 | array.append(input[i]) 126 | callnew.res = _eval(array) 127 | elif input[level+1].id == key.KEY_PARENLEFT and key.KEY_PARENRIGHT in _get_ids(input): 128 | var end = _get_ids(input).find(key.KEY_PARENRIGHT, level+2) 129 | callnew.name = input[level].value 130 | callnew.function = true 131 | callnew.builtin_function = _builtin_function(input[level]) 132 | var args: Array = [] 133 | for i in range(level+2, end): 134 | args.append(input[i]) 135 | if args.size() != 0: 136 | callnew.args = _eval_function_args(args) 137 | elif input.size() > 2: 138 | callnew.name = _eval_string(input, 0).string 139 | elif level+1 == s: 140 | callnew.name = input[level].value 141 | return callnew 142 | 143 | func _get_ids(tokens) -> Array: 144 | var arr = [] 145 | for i in tokens: 146 | arr.append(i.id) 147 | return arr 148 | 149 | func _eval_dictionary(_array: Array): 150 | var dictionaryname = Dictionaryname.new() 151 | dictionaryname.items = [] 152 | return dictionaryname 153 | 154 | func _cut_string(msg: String, level: int): 155 | var l = msg.length() 156 | return msg.right(l-level) 157 | 158 | func _eval_string(array: Array, level: int): 159 | var s: String = "" 160 | for i in range(level, level+3): 161 | s += array[i].value 162 | var stringname = Stringname.new() 163 | stringname.string = s 164 | return stringname 165 | 166 | func _eval_function_args(array: Array): 167 | var arr: Array = [] 168 | var ast_arr: Array = [] 169 | var token = Token.new() 170 | token.id = key.KEY_COMMA 171 | token.value = "," 172 | array.append(token) 173 | for i in range(0, array.size()): 174 | if array[i].id == key.KEY_COMMA: 175 | ast_arr.append(_arg_call(arr, 0)) 176 | arr = [] 177 | else: 178 | arr.append(array[i]) 179 | return ast_arr 180 | 181 | func _variable(root, input: Array, level: int, is_const: bool): 182 | var variable = Variable.new() 183 | variable.variable = input[level+1].value 184 | variable.is_const = is_const 185 | if input[level+2].id == key.KEY_COLON: 186 | variable.st = true 187 | level += 1 188 | if input[level+2].id != key.KEY_EQUAL: 189 | variable.type = input[level+2].value 190 | level += 1 191 | if input[level+2].id == key.KEY_EQUAL: 192 | variable.equ = true 193 | level += 1 194 | var array: Array = [] 195 | for i in range(level+2, input.size()): 196 | array.append(input[i]) 197 | variable.res = _eval(array) 198 | root.elem.append(variable) 199 | #print(input) 200 | 201 | func _builtin_function(function) -> bool: 202 | return (function.id == keyword.KW_NEW) 203 | 204 | func _eval(array: Array): 205 | var s: int = array.size() 206 | var variable 207 | if array[0].id == key.KEY_BRACELEFT && array[s-1].id == key.KEY_BRACERIGHT: 208 | variable = _eval_dictionary(array) 209 | return variable 210 | if array.size() == 3: 211 | if array[0].id == key.KEY_QUOTEDBL && array[2].id == key.KEY_QUOTEDBL: 212 | variable = _eval_string(array, 0) 213 | return variable 214 | variable = _new_call(array, 0) 215 | return variable 216 | 217 | func _for_in(startln: int, endln: int, level: int, root, input: Array, unit: Array, con: Array): 218 | var forloop = Forloop.new() 219 | var begin: int = -1 220 | if keyword.KW_IN in _get_ids(input): 221 | begin = _get_ids(input).find(keyword.KW_IN, level+2) 222 | var end: int = input.size() 223 | var f: Array = [] 224 | for i in range(level+1, begin): 225 | f.append(input[i]) 226 | var x: Array = [] 227 | for i in range(begin+1, end-1): 228 | x.append(input[i]) 229 | forloop.f = _new_call(f, 0) 230 | forloop.i = _new_call(x, 0) 231 | forloop.root = ast(startln+1, endln, level+1, forloop.root, unit, con) 232 | root.elem.append(forloop) 233 | 234 | func _if_cond(startln: int, endln: int, level: int, root, input: Array, unit: Array, con: Array): 235 | var ifcond = Ifcond.new() 236 | var end: int = input.size() 237 | var i: Array = [] 238 | for x in range(level+1, end-1): 239 | i.append(input[x]) 240 | ifcond.i = _new_call(i, 0) 241 | ifcond.root = ast(startln+1, endln, level+1, ifcond.root, unit, con) 242 | root.elem.append(ifcond) 243 | 244 | func _function(startln: int, endln: int, level: int, root, input: Array, unit: Array, con: Array): 245 | var function = Function.new() 246 | function.args = [] 247 | function.function = input[level+1].value 248 | var begin: int = -1 249 | if key.KEY_PARENLEFT in _get_ids(input): 250 | begin = _get_ids(input).find(key.KEY_PARENLEFT, level+2) 251 | var end: int = -1 252 | if key.KEY_PARENRIGHT in _get_ids(input): 253 | end = _get_ids(input).find(key.KEY_PARENRIGHT, begin+1) 254 | var arrow1: int = -1 255 | if key.KEY_MINUS in _get_ids(input): 256 | arrow1 = _get_ids(input).find(key.KEY_MINUS, end+1) 257 | var arrow2: int = -1 258 | if key.KEY_GREATER in _get_ids(input): 259 | arrow2 = _get_ids(input).find(key.KEY_GREATER, arrow1+1) 260 | var colon: int = -1 261 | if key.KEY_COLON in _get_ids(input): 262 | colon = _get_ids(input).find(key.KEY_COLON, end+1) 263 | if (arrow1>0 and arrow2>0): 264 | function.ret = true 265 | function.res = input[colon-1].value 266 | var add: bool = true 267 | while (end-begin > 1): 268 | if add: 269 | var stringname = Stringname.new() 270 | stringname.string = input[begin+1].value 271 | function.args.append(stringname) 272 | add = false 273 | if input[begin+1].id == key.KEY_COMMA: 274 | add = true 275 | begin += 1 276 | function.root = ast(startln+1, endln, level+1, function.root, unit, con) 277 | root.elem.append(function) 278 | #print(input) 279 | -------------------------------------------------------------------------------- /gdsbin/test/benchmark.gd: -------------------------------------------------------------------------------- 1 | class_name Benchmark 2 | 3 | var _for_time = 0 4 | var _test_results = [] 5 | const PRINT_PER_TEST_TIME = false 6 | var _test_a = 1 7 | 8 | func run() -> void: 9 | var __init__ = preload("__init__.gd").new() 10 | info("add") 11 | var start_ms: int = Time.get_ticks_msec() 12 | check(start_ms, add(), 0) 13 | info("product") 14 | start_ms = Time.get_ticks_msec() 15 | check(start_ms, product(), 3988008998000) 16 | info("rec") 17 | start_ms = Time.get_ticks_msec() 18 | check(start_ms, rec(), 0) 19 | info("arr_test") 20 | start_ms = Time.get_ticks_msec() 21 | check(start_ms, arr_test(), 1500) 22 | info("string") 23 | start_ms = Time.get_ticks_msec() 24 | check(start_ms, string(), 300000) 25 | info("pr_untyped") 26 | start_ms = Time.get_ticks_msec() 27 | check(start_ms, pr_untyped(), 655360) 28 | info("pr_typed") 29 | start_ms = Time.get_ticks_msec() 30 | check(start_ms, pr_typed(), 655360) 31 | info("i_arr_untyped") 32 | start_ms = Time.get_ticks_msec() 33 | check(start_ms, i_arr_untyped(), 0) 34 | info("i_arr_typed") 35 | start_ms = Time.get_ticks_msec() 36 | check(start_ms, i_arr_typed(), 0) 37 | info("str_arr_untyped") 38 | start_ms = Time.get_ticks_msec() 39 | check(start_ms, str_arr_untyped(), 0) 40 | info("str_arr_typed") 41 | start_ms = Time.get_ticks_msec() 42 | check(start_ms, str_arr_untyped(), 0) 43 | info("str_arr_packed") 44 | start_ms = Time.get_ticks_msec() 45 | check(start_ms, str_arr_packed(), 0) 46 | microtests() 47 | return 48 | 49 | func start() -> int: 50 | return Time.get_ticks_msec() 51 | 52 | func stop(_test_name, _time_before): 53 | const ITERATIONS = 250000 54 | var time = Time.get_ticks_msec() - _time_before 55 | if _test_name.length() != 0: 56 | var test_time = time - _for_time 57 | 58 | if PRINT_PER_TEST_TIME: 59 | # Time taken for 1 test 60 | var k = 1000000.0 / ITERATIONS 61 | test_time = k * test_time 62 | 63 | print(_test_name + ": " + str(test_time))# + " (with for: " + str(time) + ")") 64 | _test_results.append({"name" : _test_name,"time" : test_time}) 65 | return time 66 | 67 | func microtests(): 68 | const ITERATIONS = 250000 69 | print("-------------------") 70 | var _time_before = Time.get_ticks_msec() 71 | start() 72 | for i in range(0,ITERATIONS): 73 | pass 74 | _for_time = stop("", _time_before) 75 | print("For time: " + str(_for_time)) 76 | print("") 77 | if PRINT_PER_TEST_TIME: 78 | print("The following times are in microseconds taken for 1 test.") 79 | else: 80 | print("The following times are in seconds for the whole test.") 81 | print("") 82 | #------------------------------------------------------- 83 | test_empty_func() 84 | test_increment() 85 | test_increment_x5() 86 | test_increment_with_member_var() 87 | test_increment_with_local_outside_loop() 88 | test_increment_with_local_inside_loop() 89 | test_unused_local() 90 | test_divide() 91 | test_increment_with_dictionary_member() 92 | test_increment_with_array_member() 93 | test_while_time() 94 | test_if_true() 95 | test_if_true_else() 96 | test_variant_array_resize() 97 | test_variant_array_assign() 98 | test_int_array_resize() 99 | test_int_array_assign() 100 | print("-------------------") 101 | print("Done.") 102 | 103 | func str_arr_packed() -> int: 104 | const ITERATIONS: int = 80000 105 | var array: PackedStringArray = [] 106 | for i in range(0, ITERATIONS): 107 | # Insert elements. 108 | array.push_back("Godot " + str(i)) 109 | for i in range(0, ITERATIONS): 110 | # Update elements in order. 111 | array[i] = "" 112 | for _i in range(0, ITERATIONS): 113 | # Delete elements from the front (non-constant complexity). 114 | array.remove_at(0) 115 | return array.size() 116 | 117 | func str_arr_typed() -> int: 118 | const ITERATIONS: int = 80000 119 | var array: Array = [] 120 | for i in range(0, ITERATIONS): 121 | # Insert elements. 122 | array.push_back("Godot " + str(i)) 123 | for i in range(0, ITERATIONS): 124 | # Update elements in order. 125 | array[i] = "" 126 | for _i in range(0, ITERATIONS): 127 | # Delete elements from the front (non-constant complexity). 128 | array.pop_front() 129 | return array.size() 130 | 131 | func str_arr_untyped() -> int: 132 | const ITERATIONS = 80000 133 | var array = [] 134 | for i in range(0, ITERATIONS): 135 | # Insert elements. 136 | array.push_back("Godot " + str(i)) 137 | for i in range(0, ITERATIONS): 138 | # Update elements in order. 139 | array[i] = "" 140 | for _i in range(0, ITERATIONS): 141 | # Delete elements from the front (non-constant complexity). 142 | array.pop_front() 143 | return array.size() 144 | 145 | func i_arr_untyped() -> int: 146 | const ITERATIONS = 80000 147 | var array = [] 148 | for i in range(0, ITERATIONS): 149 | # Insert elements. 150 | array.push_back(i) 151 | for i in range(0, ITERATIONS): 152 | # Update elements in order. 153 | array[i] = 0 154 | for _i in range(0, ITERATIONS): 155 | # Delete elements from the front (non-constant complexity). 156 | array.pop_front() 157 | return array.size() 158 | 159 | func i_arr_typed() -> int: 160 | const ITERATIONS: int = 80000 161 | var array: Array = [] 162 | for i in range(0, ITERATIONS): 163 | # Insert elements. 164 | array.push_back(i) 165 | for i in range(0, ITERATIONS): 166 | # Update elements in order. 167 | array[i] = 0 168 | for i in range(0, ITERATIONS): 169 | # Delete elements from the front (non-constant complexity). 170 | array.pop_front() 171 | return array.size() 172 | 173 | func pr_untyped() -> int: 174 | const elems = 655360 175 | var arr = [] 176 | for x in range(elems): 177 | arr.append(randi() % elems) 178 | var acc = 0.0 179 | for e in arr: 180 | var e2 = arr[e] 181 | var e3 = arr[e2] 182 | acc += e * e2 183 | acc *= e3 + e 184 | acc = sqrt(acc) 185 | return arr.size() 186 | 187 | func pr_typed() -> int: 188 | const elems: int = 655360 189 | var arr: PackedInt32Array = [] 190 | for x in range(elems): 191 | arr.append(randi() % elems) 192 | var acc : float = 0.0 193 | for e in arr: 194 | var e2: int = arr[e] 195 | var e3: int = arr[e2] 196 | acc += e * e2 197 | acc *= e3 + e 198 | acc = sqrt(acc) 199 | return arr.size() 200 | 201 | func arr_test() -> int: 202 | var array: Array = [] 203 | while array.size() < 1500: 204 | var s: int = array.size() 205 | array.append(str(s)) 206 | var array2: Array = [] 207 | for arr_elem in array: 208 | var elem: String = str(arr_elem) 209 | var size: int = elem.length() 210 | array2.append(size) 211 | array = array2 212 | return array.size() 213 | 214 | func string() -> int: 215 | var x : String = "" 216 | for i in range(0, 300000): 217 | x += " " 218 | return x.length() 219 | 220 | func add() -> int: 221 | var x := -10000000 222 | for i in range(0, 10000000): 223 | x += 1 224 | return x 225 | 226 | func product() -> int: 227 | var prod: int = 0 228 | for x in range(1, 2000): 229 | for y in range(1, 2000): 230 | prod += x*y 231 | prod -= x 232 | prod -= y 233 | return prod 234 | 235 | func rec() -> int: 236 | for x in range(1, 10): 237 | var c: int = 600 238 | while (c > 0): 239 | recursion(c) 240 | c-=1 241 | return recursion(0) 242 | 243 | func recursion(count: int) -> int: 244 | if count > 0: 245 | return recursion(count-1) 246 | else: 247 | return 0 248 | 249 | func info(test: String) -> void: 250 | printraw(test.to_upper() + "...") 251 | 252 | func not_passed() -> void: 253 | print(" [FAILED]") 254 | 255 | func passed() -> void: 256 | print(" [OK]") 257 | 258 | func check(start_ms: int, _a, b) -> void: 259 | if _a != b: 260 | not_passed() 261 | else: 262 | passed() 263 | var result_ms: float = Time.get_ticks_msec()-start_ms 264 | print("Time to run: " + str(result_ms/1000) + "s") 265 | return 266 | 267 | 268 | #------------------------------------------------------------------------------- 269 | func test_empty_func(): 270 | const ITERATIONS = 250000 271 | var _time_before = start() 272 | 273 | for i in range(0,ITERATIONS): 274 | empty_func() 275 | 276 | stop("Empty func (void function call cost)", _time_before) 277 | 278 | func empty_func(): 279 | pass 280 | 281 | #------------------------------------------------------------------------------- 282 | func test_increment(): 283 | const ITERATIONS = 250000 284 | var __a = 0 285 | var _time_before = start() 286 | 287 | for i in range(0,ITERATIONS): 288 | __a += 1 289 | 290 | stop("Increment", _time_before) 291 | 292 | #------------------------------------------------------------------------------- 293 | func test_increment_x5(): 294 | const ITERATIONS = 250000 295 | var _a = 0 296 | var _time_before = start() 297 | 298 | for i in range(0,ITERATIONS): 299 | _a += 1 300 | _a += 1 301 | _a += 1 302 | _a += 1 303 | _a += 1 304 | 305 | stop("Increment x5", _time_before) 306 | 307 | #------------------------------------------------------------------------------- 308 | func test_increment_with_member_var(): 309 | const ITERATIONS = 250000 310 | var _a = 0 311 | var _time_before = start() 312 | 313 | for i in range(0,ITERATIONS): 314 | _a += _test_a 315 | 316 | stop("Increment with member var", _time_before) 317 | 318 | #------------------------------------------------------------------------------- 319 | func test_increment_with_local_outside_loop(): 320 | const ITERATIONS = 250000 321 | var _a = 0 322 | var b = 1 323 | var _time_before = start() 324 | 325 | for i in range(0,ITERATIONS): 326 | _a += b 327 | 328 | stop("Increment with local (outside loop)", _time_before) 329 | 330 | #------------------------------------------------------------------------------- 331 | func test_increment_with_local_inside_loop(): 332 | const ITERATIONS = 250000 333 | var _a = 0 334 | var _time_before = start() 335 | 336 | for i in range(0,ITERATIONS): 337 | var b = 1 338 | _a += b 339 | 340 | stop("Increment with local (inside loop)", _time_before) 341 | 342 | #------------------------------------------------------------------------------- 343 | func test_unused_local(): 344 | const ITERATIONS = 250000 345 | var _time_before = start() 346 | 347 | for i in range(0,ITERATIONS): 348 | var _b = 1 349 | 350 | stop("Unused local (declaration cost)", _time_before) 351 | 352 | #------------------------------------------------------------------------------- 353 | func test_divide(): 354 | const ITERATIONS = 250000 355 | var _time_before = start() 356 | 357 | var _a = 9999 358 | for i in range(0,ITERATIONS): 359 | _a /= 1.01 360 | 361 | stop("Divide", _time_before) 362 | 363 | #------------------------------------------------------------------------------- 364 | func test_increment_with_dictionary_member(): 365 | const ITERATIONS = 250000 366 | var _time_before = start() 367 | 368 | var _a = 0 369 | var dic = {"b" : 1} 370 | for i in range(0,ITERATIONS): 371 | _a += dic["b"] 372 | 373 | stop("Increment with dictionary member", _time_before) 374 | 375 | #------------------------------------------------------------------------------- 376 | func test_increment_with_array_member(): 377 | const ITERATIONS = 250000 378 | var _time_before = start() 379 | 380 | var _a = 0 381 | var arr = [1] 382 | for i in range(0,ITERATIONS): 383 | _a += arr[0] 384 | 385 | stop("Increment with array member", _time_before) 386 | 387 | #------------------------------------------------------------------------------- 388 | func test_while_time(): 389 | const ITERATIONS = 250000 390 | var _time_before = start() 391 | 392 | var i = 0 393 | while i < ITERATIONS: 394 | i += 1 395 | 396 | print("While time (for equivalent with manual increment): " + str(Time.get_ticks_msec() - _time_before)) 397 | 398 | #------------------------------------------------------------------------------- 399 | func test_if_true(): 400 | const ITERATIONS = 250000 401 | var _time_before = start() 402 | const boolean: bool = true 403 | for i in range(0,ITERATIONS): 404 | if boolean: 405 | pass 406 | 407 | stop("if(true) time", _time_before) 408 | 409 | #------------------------------------------------------------------------------- 410 | func test_if_true_else(): 411 | const ITERATIONS = 250000 412 | var _time_before = start() 413 | const boolean: bool = true 414 | for i in range(0,ITERATIONS): 415 | if boolean: 416 | pass 417 | else: 418 | pass 419 | 420 | stop("if(true)else time", _time_before) 421 | 422 | #------------------------------------------------------------------------------- 423 | func test_variant_array_resize(): 424 | const ITERATIONS = 250000 425 | var _time_before = start() 426 | for i in range(0,ITERATIONS): 427 | var line = [] 428 | line.resize(1000) 429 | stop("VariantArray resize", _time_before) 430 | 431 | #------------------------------------------------------- 432 | func test_variant_array_assign(): 433 | const ITERATIONS = 250000 434 | var v_array = [] 435 | v_array.resize(100) 436 | 437 | var _time_before = start() 438 | for i in range(0, ITERATIONS): 439 | v_array[42] = 0 440 | 441 | stop("VariantArray set element", _time_before) 442 | 443 | #------------------------------------------------------- 444 | func test_int_array_resize(): 445 | const ITERATIONS = 250000 446 | var _time_before = start() 447 | for i in range(0,ITERATIONS): 448 | var line: PackedInt32Array = [] 449 | line.resize(1000) 450 | 451 | stop("PoolIntArray resize", _time_before) 452 | 453 | #------------------------------------------------------- 454 | func test_int_array_assign(): 455 | const ITERATIONS = 250000 456 | var i_array: PackedInt32Array = [] 457 | i_array.resize(100) 458 | 459 | var _time_before = start() 460 | for i in range(0, ITERATIONS): 461 | i_array[42] = 0 462 | 463 | stop("PoolIntArray set element", _time_before) 464 | -------------------------------------------------------------------------------- /gdsbin/transpiler.gd: -------------------------------------------------------------------------------- 1 | class_name Transpiler 2 | 3 | ## GDScript Transpiler Class 4 | ## 5 | ## Transpiler for converting any GDScript code to Python 6 | ## using search-and-replace syntax 7 | ## 8 | ## 9 | 10 | ## Properties class instance 11 | var props = Props.new() 12 | var defs = Defs.new() 13 | 14 | ## Function to split script into lines and analyze each one. 15 | ## Imports are added to transpiled python script if required. 16 | func transpile(content: String, package_name: String) -> String: 17 | var t: String = "" 18 | for line in content.split("\n"): 19 | if not line.begins_with("##"): 20 | t += analyze(line, package_name) 21 | if defs.sys_imp: 22 | t = "import sys" + "\n" + t 23 | if defs.subprocess_imp: 24 | t = "import subprocess" + "\n" + t 25 | if defs.os_imp: 26 | t = "import os" + "\n" + t 27 | if defs.rand_imp: 28 | t = "import random" + "\n" + t 29 | if defs.math_imp: 30 | t = "import math" + "\n" + t 31 | if defs.datetime_imp: 32 | t = "import datetime" + "\n" + t 33 | if defs.py_imp: 34 | t = "#!/usr/bin/env python" + "\n" + t 35 | if defs.left_def: 36 | t += "def left(s, amount):" 37 | t += "\n" 38 | t += " return s[:amount]" 39 | t += "\n" 40 | if defs.right_def: 41 | t += "def right(s, amount):" 42 | t += "\n" 43 | t += " return s[len(s)-amount:]" 44 | t += "\n" 45 | if defs.execute_def: 46 | t += "def py_execute(program, args):" 47 | t += "\n" 48 | t += " args = [program] + args" 49 | t += "\n" 50 | t += " proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)" 51 | t += "\n" 52 | t += " stdout, stderr = proc.communicate()" 53 | t += "\n" 54 | t += " return [stdout.decode('utf-8')]" 55 | t += "\n" 56 | if defs.execute_pipe_def: 57 | t += "def py_execute_pipe(program, args):" 58 | t += "\n" 59 | t += " args = [program] + args" 60 | t += "\n" 61 | t += " proc = subprocess.Popen(args, shell=False)" 62 | t += "\n" 63 | t += " proc.communicate()" 64 | t += "\n" 65 | t += " return {'stdio': False}" 66 | t += "\n" 67 | if defs.thread_def: 68 | t += "class Thread:" 69 | t += "\n" 70 | t += " def start(self, function):" 71 | t += "\n" 72 | t += " return" 73 | t += "\n" 74 | t += " def is_alive(self):" 75 | t += " return True" 76 | t += "\n" 77 | if defs.resize_def: 78 | t += "def resize(arr, size):" 79 | t += "\n" 80 | t += " i" 81 | t += "f" 82 | t += " len(arr)==" 83 | t += "0" 84 | t += ":" 85 | t += "\n" 86 | t += " arr.append(None)" 87 | t += "\n" 88 | t += " arr *= size" 89 | t += "\n" 90 | t += " return arr" 91 | t += "\n" 92 | if defs.init_def: 93 | t += "i" 94 | t += "f" 95 | t += " __name__==" 96 | t += '"' 97 | t += "__main__" 98 | t += '"' 99 | t += ":" 100 | t += "\n" 101 | t += " _init()" 102 | t += "\n" 103 | if defs.classname_def: 104 | t += "def get_script():" 105 | t += "\n" 106 | t += " class Script:" 107 | t += "\n" 108 | t += " def get_global_name():" 109 | t += "\n" 110 | t += " return class_name" 111 | t += "\n" 112 | t += " return Script" 113 | return t 114 | 115 | 116 | ## Function to output contents of a file using File compatibility class 117 | func read(path: String) -> String: 118 | var file: File = File.new() 119 | file.open(path, file.FileOpts.READ) 120 | var string: String = file.get_as_text() 121 | file.close() 122 | return string 123 | 124 | func generate_setup(path: String, package_name: String, author: String, author_email: String, project_url: String, download_url: String, documentation_url: String, source_url: String, tracker_url: String, description: String, proj_license: String) -> void: 125 | var content: String = "" 126 | var file: Array = props.get_setup(package_name, author, author_email, project_url, download_url, documentation_url, source_url, tracker_url, description, proj_license) 127 | for line in file: 128 | content += line + "\n" 129 | save(path, content) 130 | 131 | func generate_pyproject(path: String, setuptools_min_ver: int): 132 | var content: String = "" 133 | var file: Array = props.get_pyproject_toml(setuptools_min_ver) 134 | for line in file: 135 | content += line + "\n" 136 | save(path, content) 137 | 138 | ## Function to write final output to a file using File compatibility class 139 | func save(path: String, content: String) -> void: 140 | var file: File = File.new() 141 | file.open(path, file.FileOpts.WRITE) 142 | file.store_string(content) 143 | file.close() 144 | 145 | 146 | func check_match(l: String): 147 | var out: String = "" 148 | for i in l: 149 | if i != " " && i != " ": 150 | out += i 151 | var cond: bool = out.ends_with(":") 152 | cond = (cond and not out.begins_with("for")) 153 | cond = (cond and not out.begins_with("while")) 154 | cond = (cond and not out.begins_with("if")) 155 | cond = (cond and not out.contains("(")) 156 | cond = (cond and not out.contains(")")) 157 | cond = (cond and not out.contains("match")) 158 | cond = (cond and not out.begins_with("else")) 159 | cond = (cond and not out.contains("elif")) 160 | if cond: 161 | var args: Array = l.split(" ") 162 | var count = 0 163 | for arg_str in args: 164 | if arg_str != "": 165 | l = arg_str 166 | else: 167 | count+=1 168 | l = "case " + l 169 | while count > 0: 170 | l = " " + l 171 | count -= 1 172 | return l 173 | 174 | func check_format(l: String): 175 | while l.contains("% [") and l.ends_with("]"): 176 | l = l.replace("% [", "% (") 177 | var index = l.length()-1 178 | l[index] = ")" 179 | while l.contains("%[") and l.ends_with("]"): 180 | l = l.replace("%[", "% (") 181 | var index = l.length()-1 182 | l[index] = ")" 183 | return l 184 | 185 | func check_new(l: String): 186 | const NAMES: Array = ["preload", "load"] 187 | for n in NAMES: 188 | var name: String = n + "(" + '"' 189 | var search: String = ".gd" + '"' 190 | search += ").new()" 191 | if l.contains(name) && l.contains(search): 192 | l = l.replace(name, "") 193 | l = l.replace(search, "") 194 | name = l.split("=")[1] 195 | name = name.replace(" ", "") 196 | name = name.replace("//", "") 197 | var lvl = name.split("/") 198 | lvl = lvl.size() 199 | search = "" 200 | for i in range(lvl-1): 201 | search += name.split("/")[i] + "." 202 | search = search.left(search.length()-1) 203 | name = name.split("/")[lvl-1] 204 | while search.begins_with("res:"): 205 | search = search.replace("res:", "") 206 | while l.contains(" = "): 207 | l = l.split(" = ")[0] 208 | while l.contains("="): 209 | l = l.split("=")[0] 210 | while not l.contains("var " + name): 211 | l = l.replace(name, search + "." + name + " = " + name.to_upper() + ".new()") 212 | while l.contains("var " + name): 213 | l = l.replace("var " + name, search + "." + name + " = " + name.to_upper() + ".new()") 214 | var s = l.replace(" ", "") 215 | if s.begins_with("."): 216 | l = l.replace(s, "") 217 | s = s.right(s.length() - 1) 218 | l = l+s 219 | return l 220 | 221 | ## Function for splitting lines (excluding double quoted Strings) into 222 | ## readable GDScript syntax expressions which later can be converted 223 | func analyze(l: String, package_name: String) -> String: 224 | l = check_match(l) 225 | l = check_new(l) 226 | l = check_format(l) 227 | var out: String = "" 228 | var quote: String = "'" 229 | quote += '"' 230 | quote += "'" 231 | var string_prev: Array = l.split(quote) 232 | var c: int = 0 233 | for ii in range(0, string_prev.size()): 234 | var string: Array = string_prev[ii].split('"') 235 | if ii > 0: 236 | out += "'" 237 | out += '"' 238 | out += "'" 239 | for i in range(0, string.size()): 240 | if ii > 0: 241 | out += string[i] 242 | elif c ^ 1 != c + 1: 243 | out += '"' + string[i] + '"' 244 | else: 245 | out += translate(string[i], package_name) 246 | c += 1 247 | if out.length() > 0: 248 | var res: String = "res" 249 | res += "://" 250 | while out.contains(res): 251 | out = out.replace(res, "") 252 | while out.contains("if") and out.ends_with('"'): 253 | out += ":" 254 | if out.ends_with(" "): 255 | out = out.left(out.length() - 1) 256 | out += "\n" 257 | return out 258 | 259 | 260 | ## Dictionary function which converts known GDScript arguments 261 | func dict(arg: String) -> String: 262 | var e: String = "" 263 | if arg.length() == 0: 264 | return e 265 | if arg in props.op: 266 | e += arg 267 | e += " " 268 | return e 269 | if arg == "File.new()": 270 | e += props.repl_dict[arg] 271 | e += '"' 272 | e += '"' 273 | e += " " 274 | return e 275 | if arg == "Thread.new()": 276 | e += props.repl_dict[arg] 277 | e += " Thread()" 278 | e += " " 279 | defs.thread_def = true 280 | return e 281 | while arg.begins_with(" "): 282 | e += " " 283 | arg = arg.right(arg.length() - 1) 284 | var con: bool = false 285 | while arg.contains(".new()"): 286 | arg = arg.replace(".new()", "") 287 | if not arg in props.gd_class && not arg in props.gds_class && not arg in props.gds_deps: 288 | props.gds_deps.append(arg) 289 | arg = "import " + arg 290 | con = true 291 | if arg in props.types: 292 | return e 293 | if arg in props.extend: 294 | return e 295 | if ( 296 | arg 297 | in [ 298 | "-s", 299 | "var", 300 | "const", 301 | "Node", 302 | "SceneTree", 303 | "extends", 304 | "File" 305 | ] 306 | ): 307 | e += props.repl_dict[arg] 308 | return e 309 | if arg in props.gds_deps: 310 | return e 311 | if ( 312 | arg 313 | in [ 314 | "func", 315 | "true", 316 | "false", 317 | "&&", 318 | "||", 319 | ] 320 | ): 321 | e += props.repl_dict[arg] 322 | e += " " 323 | return e 324 | if arg == "_ready()" or arg == "_init()": 325 | e += props.repl_dict[arg] 326 | e += " " 327 | defs.init_def = true 328 | return e 329 | if arg.ends_with("_ready()"): 330 | arg = arg.replace("_ready()", props.repl_dict["_ready()"]) 331 | e += arg 332 | e += " " 333 | return e 334 | if arg.ends_with("_init()"): 335 | arg = arg.replace("_init()", props.repl_dict["_init()"]) 336 | e += arg 337 | e += " " 338 | return e 339 | if arg.contains("null"): 340 | arg = arg.replace("null", props.repl_dict["null"]) 341 | e += arg 342 | e += " " 343 | return e 344 | if arg == "OS.execute(program,args,stdout)": 345 | e += props.repl_dict[arg] 346 | defs.subprocess_imp = true 347 | defs.execute_def = true 348 | return e 349 | if arg.ends_with("OS.execute_with_pipe(program,args)"): 350 | arg = arg.replace("OS.execute_with_pipe(program,args)", props.repl_dict["OS.execute_with_pipe(program,args)"]); 351 | e += arg 352 | defs.subprocess_imp = true 353 | defs.execute_pipe_def = true 354 | return e 355 | if arg == "quit()" or arg == "self.quit()": 356 | e += props.repl_dict[arg] 357 | e += " " 358 | defs.sys_imp = true 359 | return e 360 | if arg == "#!/usr/bin/godot": 361 | e += props.repl_dict[arg] 362 | defs.py_imp = true 363 | e += " " 364 | return e 365 | while arg.contains(".to_lower()"): 366 | arg = arg.replace(".to_lower()", ".lower()") 367 | con = true 368 | while arg.contains(".to_upper()"): 369 | arg = arg.replace(".to_upper()", ".upper()") 370 | con = true 371 | while arg.contains("printraw("): 372 | arg = arg.replace("printraw(", "sys.stdout.write(") 373 | defs.sys_imp = true 374 | con = true 375 | while arg.contains(".resize("): 376 | arg = arg.replace("resize(", "") 377 | defs.resize_def = true 378 | if arg.contains("("): 379 | arg = arg.replace("(", "(resize(") 380 | else: 381 | arg = "resize(" + arg 382 | arg = arg.replace(".", ", ") 383 | con = true 384 | while arg.contains(".size()"): 385 | arg = arg.replace(".size()", ")") 386 | if arg.contains("("): 387 | arg = arg.replace("(", "(len(") 388 | else: 389 | arg = "len(" + arg 390 | con = true 391 | while arg.contains(".length()"): 392 | arg = arg.replace(".length()", ")") 393 | if arg.contains("("): 394 | arg = arg.replace("(", "(len(") 395 | else: 396 | arg = "len(" + arg 397 | con = true 398 | while arg.contains(".right("): 399 | arg = arg.replace(".right(", ", ") 400 | arg = "right(" + arg 401 | defs.right_def = true 402 | con = true 403 | while arg.contains(".left("): 404 | arg = arg.replace(".left(", ", ") 405 | arg = "left(" + arg 406 | defs.left_def = true 407 | con = true 408 | while arg.contains(".open"): 409 | arg = arg.replace(".open", " = open") 410 | con = true 411 | while arg.contains(".begins_with"): 412 | arg = arg.replace(".begins_with", ".startswith") 413 | con = true 414 | while arg.contains(".ends_with"): 415 | arg = arg.replace(".ends_with", ".endswith") 416 | con = true 417 | while arg.contains(".find("): 418 | arg = arg.replace(".find(", ".index(") 419 | con = true 420 | while arg.contains(".contains"): 421 | arg = arg.replace(".contains", ".find") 422 | arg = "0 <= " + arg 423 | con = true 424 | while arg.contains("file.FileOpts.READ"): 425 | var r: String = "" 426 | r += '"' 427 | r += "r" 428 | r += '"' 429 | arg = arg.replace("file.FileOpts.READ", r) 430 | con = true 431 | while arg.contains("file.FileOpts.WRITE"): 432 | var w: String = "" 433 | w += '"' 434 | w += "w" 435 | w += '"' 436 | arg = arg.replace("file.FileOpts.WRITE", w) 437 | con = true 438 | while arg.contains("print()"): 439 | arg = arg.replace("print()", "print('\\n')") 440 | con = true 441 | while arg.contains("randi()"): 442 | arg = arg.replace("randi()", "random.randint(0, 2147483647)") 443 | defs.rand_imp = true 444 | con = true 445 | while arg.contains(".push_back("): 446 | arg = arg.replace(".push_back(", ".append(") 447 | con = true 448 | while arg.contains(".pop_front()"): 449 | arg = arg.replace(".pop_front()", ".pop(0)") 450 | con = true 451 | while arg.contains(".remove_at("): 452 | arg = arg.replace(".remove_at(", ".pop(") 453 | con = true 454 | while arg.contains(".get_as_text"): 455 | arg = arg.replace(".get_as_text", ".read") 456 | con = true 457 | while arg.contains(".store_string"): 458 | arg = arg.replace(".store_string", ".write") 459 | con = true 460 | while arg.contains(".clear()"): 461 | arg = arg.replace(".clear()", " = []") 462 | con = true 463 | while arg.contains("_self,"): 464 | arg = arg.replace("_self,", "") 465 | con = true 466 | while arg.contains("_self"): 467 | arg = arg.replace("_self", "self") 468 | con = true 469 | while arg.contains("Time.get_ticks_msec()"): 470 | arg = arg.replace("Time.get_ticks_msec()", "int(float(datetime.datetime.now().strftime('%s.%f')) * 1000)") 471 | defs.datetime_imp = true 472 | con = true 473 | while arg.contains("OS.get_cmdline_args()"): 474 | arg = arg.replace("OS.get_cmdline_args()", "sys.argv") 475 | defs.sys_imp = true 476 | con = true 477 | while arg.contains("Engine.get_version_info()"): 478 | arg = arg.replace("Engine.get_version_info()", str(Engine.get_version_info())) 479 | con = true 480 | while arg.contains("sqrt(") and not arg.contains("math.sqrt("): 481 | arg = arg.replace("sqrt(", "math.sqrt(") 482 | defs.math_imp = true 483 | con = true 484 | while arg.contains("atan2(") and not arg.contains("math.atan2("): 485 | arg = arg.replace("atan2(", "math.atan2(") 486 | defs.math_imp = true 487 | con = true 488 | while arg.contains("sin(") and not arg.contains("math.sin("): 489 | arg = arg.replace("sin(", "math.sin(") 490 | defs.math_imp = true 491 | con = true 492 | while arg.contains("cos(") and not arg.contains("math.cos("): 493 | arg = arg.replace("cos(", "math.cos(") 494 | defs.math_imp = true 495 | con = true 496 | var found: bool = false 497 | for type in props.types: 498 | while arg.begins_with(type): 499 | found = true 500 | arg = arg.replace(type, "") 501 | break 502 | if found: 503 | e += arg 504 | e += " " 505 | return e 506 | if con: 507 | e += arg 508 | e += " " 509 | return e 510 | if defs.debug: 511 | print("DEBUG: " + arg) 512 | e += arg 513 | e += " " 514 | return e 515 | 516 | 517 | ## Translation function for removing gdscript type hints and internal types 518 | func translate(e: String, package_name: String) -> String: 519 | if e == ",": 520 | return "," 521 | if e == "": 522 | return "" 523 | var cmd: String = e 524 | while cmd.begins_with(" "): 525 | cmd = cmd.right(cmd.length() - 1) 526 | if cmd.begins_with("#") and not cmd.begins_with("#!"): 527 | return e 528 | if e.begins_with("class_name"): 529 | defs.classname_def = true 530 | var classn: String = e.split(" ")[0] 531 | var script_name : String = e.split(" ")[1] 532 | e = e.replace(classn + " " + script_name, "const " + classn + " = " + '"' + script_name + '"') 533 | props.gds_deps.append(script_name) 534 | if e.contains("extends"): 535 | var script_name : String = e.split(" ")[1] 536 | if script_name not in props.types: 537 | props.extend.append(script_name) 538 | var var_test: String = e 539 | while var_test.begins_with(" "): 540 | var_test = var_test.replace(" ", "") 541 | for variable in ["var ", "const "]: 542 | if var_test.begins_with(variable) and not var_test.contains("="): 543 | if var_test.contains("#"): 544 | e = e.split("#")[0] + "= null #" + e.split("#")[1] 545 | else: 546 | e += " = null" 547 | var args: Array = e.split(" ") 548 | e = "" 549 | for arg in args: 550 | e += dict(arg) 551 | while e.contains(" "): 552 | e = e.replace(" ", " ") 553 | while e.contains(": ="): 554 | e = e.replace(": =", "=") 555 | while e.contains(":="): 556 | e = e.replace(":=", "=") 557 | while e.contains(": )"): 558 | e = e.replace(": )", ")") 559 | while e.contains(":)"): 560 | e = e.replace(":)", ")") 561 | while e.contains(": ,"): 562 | e = e.replace(": ,", ",") 563 | while e.contains(":,"): 564 | e = e.replace(":,", ",") 565 | while e.contains(" -> "): 566 | e = e.replace(" -> ", "") 567 | while e.contains("DisplayServer"): 568 | e = "" 569 | while e.contains("OS"): 570 | e = "" 571 | var index : int = 0 572 | for gds_name in props.gds_deps: 573 | while e.contains(gds_name.to_lower() + " = import " + gds_name): 574 | e = e.replace(gds_name.to_lower() + " = import " + gds_name, "import " + gds_name.to_lower()) 575 | if e.contains("."): 576 | if e.contains(package_name): 577 | var packages: Array = e.split(".") 578 | var l: int = packages.size() 579 | var imp : String = packages[l-1] 580 | var imp_b : String = imp.split(" ")[1] 581 | var package: String = "" 582 | while (l>1): 583 | package = packages[l-2] + "/" + package 584 | l-=1 585 | package = package.left(package.length() - 1) 586 | defs.os_imp = true 587 | e = " sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), '..')))" 588 | e += "\n" 589 | while package.contains(" "): 590 | e += " " 591 | package = package.right(package.length() - 1) 592 | e += "import " + package.replace("/", ".") + "." + imp_b 593 | props.gds_deps[index] = "../" + package + "/" + imp_b 594 | else: 595 | # Shallow copy, https://stackoverflow.com/a/11173076 596 | var gds = gds_name.to_lower() 597 | var b = package_name + "." + gds 598 | var str1 = "import " + gds 599 | var str2 = "import " + b + "; " 600 | var str3 = gds + " = type(" + b + ")(" + b + ".__name__, " + b + ".__doc__); " 601 | var str4 = gds + ".__dict__.update(" + b + ".__dict__)" 602 | e = e.replace(str1, str2 + str3 + str4) 603 | index += 1 604 | return e 605 | 606 | func set_def(arr: Array): 607 | if arr.size() != 17: 608 | defs.py_imp = false 609 | defs.debug = false 610 | defs.verbose = false 611 | defs.init_def = false 612 | defs.thread_def = false 613 | defs.resize_def = false 614 | defs.right_def = false 615 | defs.left_def = false 616 | defs.execute_def = false 617 | defs.execute_pipe_def = false 618 | defs.classname_def = false 619 | defs.sys_imp = false 620 | defs.subprocess_imp = false 621 | defs.os_imp = false 622 | defs.math_imp = false 623 | defs.rand_imp = false 624 | defs.datetime_imp = false 625 | return 626 | defs.py_imp = (defs.py_imp || arr[0]) 627 | defs.debug = (defs.debug || arr[1]) 628 | defs.verbose = (defs.verbose || arr[2]) 629 | defs.init_def = (defs.init_def || arr[3]) 630 | defs.thread_def = (defs.thread_def || arr[4]) 631 | defs.resize_def = (defs.resize_def || arr[5]) 632 | defs.right_def = (defs.right_def || arr[6]) 633 | defs.left_def = (defs.left_def || arr[7]) 634 | defs.execute_def = (defs.execute_def || arr[8]) 635 | defs.execute_pipe_def = (defs.execute_pipe_def || arr[9]) 636 | defs.classname_def = (defs.classname_def || arr[10]) 637 | defs.sys_imp = (defs.sys_imp || arr[11]) 638 | defs.subprocess_imp = (defs.sys_imp || arr[12]) 639 | defs.os_imp = (defs.os_imp || arr[13]) 640 | defs.math_imp = (defs.math_imp || arr[14]) 641 | defs.rand_imp = (defs.math_imp || arr[15]) 642 | defs.datetime_imp = (defs.datetime_imp || arr[16]) 643 | 644 | func get_def() -> Array: 645 | return [defs.py_imp, defs.debug, defs.verbose, defs.init_def, defs.thread_def, defs.resize_def, defs.right_def, defs.left_def, defs.execute_def, defs.execute_pipe_def, defs.classname_def, defs.sys_imp, defs.subprocess_imp, defs.os_imp, defs.math_imp, defs.rand_imp, defs.datetime_imp] 646 | --------------------------------------------------------------------------------