├── 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 |
--------------------------------------------------------------------------------
/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 |
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 |
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 | [](https://downloads.tuxfamily.org/godotengine/4.0/)
7 | [](LICENSE.md)
8 | [](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 | [](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 |
--------------------------------------------------------------------------------