diff --git a/CHANGELOG.md b/CHANGELOG.md index b4f4b51..199d74a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Complete regex support - Enums +### Changed +- Made the repl slightly nicer to look at + ## [2.0.1] - 2021-10-18 ### Fixed - Fixed what happens when using `||` and `&&` if you had an expression after the operators. If you ran `"A" == "A" || "A" == "B"`, it would interpret it as `("A" == "A" || "A") == "B"`, so it would return false instead of true. diff --git a/README.md b/README.md index 6206021..c51974e 100644 --- a/README.md +++ b/README.md @@ -9,56 +9,56 @@ ParaCode also has many methods that have functional language characteristics for Later I plan to rewrite ParaCode in C/C++ for better speed, efficiency. I plan to keep ParaCode code and the standard library similar to how it is today. -[vars](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/00_vars.md) - How to declare and use variables +[vars](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/00_vars.md) - How to declare and use variables -[functions](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/10_functions.md) - Writing and calling functions +[functions](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/10_functions.md) - Writing and calling functions -[strings](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/15_strings.md) - Strings operations and interpolation +[strings](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/15_strings.md) - Strings operations and interpolation -[operators](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/16_operators.md) - Available operators + Operator overloading +[operators](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/16_operators.md) - Available operators + Operator overloading -[types](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/20_types.md) - Custom types +[types](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/20_types.md) - Custom types -[proto](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/30_proto.md) - Extending types using prototypical inheritance +[proto](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/30_proto.md) - Extending types using prototypical inheritance -[macros](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/35_macros.md) - Macros +[macros](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/35_macros.md) - Macros -[arrays](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/40_arrays.md) - Array operations +[arrays](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/40_arrays.md) - Array operations -[dictionary](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/41_dictionary.md) - Dictionary operations +[dictionary](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/41_dictionary.md) - Dictionary operations -[iterators](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/50_iterators.md) - Building custom iterator objects +[iterators](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/50_iterators.md) - Building custom iterator objects -[random](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/55_random.md) - Random number generation +[random](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/55_random.md) - Random number generation -[modules](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/60_modules.md) - Modules +[modules](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/60_modules.md) - Modules -[packages](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/61_packages.md) - Packages +[packages](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/61_packages.md) - Packages -[console](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/70_console.md) - Console input and output +[console](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/70_console.md) - Console input and output -[files](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/80_files.md) - File reading and writing +[files](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/80_files.md) - File reading and writing -[json](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#doc/81_json.md) - JSON reading and writing +[json](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/doc/81_json.md) - JSON reading and writing ### Examples -[embedding](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#examples/embed.py) +[embedding](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/examples/embed.py) -[numbers](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#examples/numbers.para) +[numbers](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/examples/numbers.para) -[strings](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#examples/string.para) +[strings](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/examples/string.para) -[patching](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#examples/patching.para) +[patching](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/examples/patching.para) -[operator overloading](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#examples/operator_overloading.para) +[operator overloading](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/examples/operator_overloading.para) -[tic tac toe](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#examples/ttt.para) +[tic tac toe](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/examples/ttt.para) -[pythagorean theorem calculator](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#examples/pythagorean.para) +[pythagorean theorem calculator](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/examples/pythagorean.para) -[rule110](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#examples/rule110.para) +[rule110](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/examples/rule110.para) Be sure to check out our TicTacToe example! Start the REPL by running `main.py` and call `tictactoe();` to try it out! @@ -69,4 +69,4 @@ sh update.sh ``` Or, to install and update ParaCode, run everything from `update.sh`. -You can find the [Changelog](https://replit.com/@DaRubyMiner360/ParaCode-Rewrite#CHANGELOG.md) here. +You can find the [Changelog](https://github.com/DaRubyMiner360/ParaCode/blob/rewrite/CHANGELOG.md) here. diff --git a/interpreter/env/builtins.py b/interpreter/env/builtins.py index 794507d..3d675e5 100644 --- a/interpreter/env/builtins.py +++ b/interpreter/env/builtins.py @@ -262,14 +262,9 @@ def builtin_str_replace(arguments): value = arguments.arguments[0].extract_value() toReplace = str(arguments.arguments[1].extract_value()) replaceWith = str(arguments.arguments[2].extract_value()) - - result = value - - if len(arguments.arguments) > 3: - amount = int(str(arguments.arguments[3].extract_value())) - result = value.replace(toReplace, replaceWith, amount) - else: - result = value.replace(toReplace, replaceWith) + amount = int(str(arguments.arguments[3].extract_value())) + + result = value.replace(toReplace, replaceWith, amount) return BasicValue(result) @@ -300,6 +295,32 @@ def builtin_str_totitle(arguments): return BasicValue(result) +def builtin_str_center(arguments): + interpreter = arguments.interpreter + this_object = arguments.this_object + + value = arguments.arguments[0].extract_value() + width = arguments.arguments[1].extract_value() + fillchar = arguments.arguments[2].extract_value() + result = value.center(width, fillchar) + + return BasicValue(result) + +def builtin_get_color(arguments): + color = arguments.arguments[0].extract_value() + result = "" + if color == 0: + result = LogColor.Default + elif color == 1: + result = LogColor.Error + elif color == 2: + result = LogColor.Warning + elif color == 3: + result = LogColor.Info + elif color == 4: + result = LogColor.Bold + return BasicValue(color) + def builtin_regex_compile(arguments): interpreter = arguments.interpreter this_object = arguments.this_object @@ -2364,6 +2385,9 @@ def builtin_os_scandir(arguments): return BasicValue(os.scandir(arguments.arguments[0].extract_value())) return BasicValue(os.scandir()) +def builtin_os_get_terminal_size(arguments): + return BasicValue(list(os.get_terminal_size())) + def builtin_clear(arguments): # Windows if os.name == 'nt': @@ -2382,9 +2406,9 @@ def builtin_quit(arguments): def builtin_sysexit(arguments): if len(arguments.arguments) > 0: - sys.exit(arguments.arguments[0].extract_value()) + sys.exit(arguments.arguments[0].extract_value()) else: - sys.exit() + sys.exit() return BasicValue(None) diff --git a/interpreter/env/globals.py b/interpreter/env/globals.py index 1253d4b..4a563c5 100644 --- a/interpreter/env/globals.py +++ b/interpreter/env/globals.py @@ -102,6 +102,7 @@ def __init__(self): ('__intern_str_tolower__', VariableType.Function, BuiltinFunction("__intern_str_tolower__", None, builtin_str_tolower)), ('__intern_str_toupper__', VariableType.Function, BuiltinFunction("__intern_str_toupper__", None, builtin_str_toupper)), ('__intern_str_totitle__', VariableType.Function, BuiltinFunction("__intern_str_totitle__", None, builtin_str_totitle)), + ('__intern_str_center__', VariableType.Function, BuiltinFunction("__intern_str_center__", None, builtin_str_center)), ('__intern_regex_compile__', VariableType.Function, BuiltinFunction("__intern_regex_compile__", None, builtin_regex_compile)), ('__intern_regex_search__', VariableType.Function, BuiltinFunction("__intern_regex_search__", None, builtin_regex_search)), @@ -343,6 +344,7 @@ def __init__(self): ('__intern_os_replace__', VariableType.Function, BuiltinFunction("__intern_os_replace__", None, builtin_os_replace)), ('__intern_os_rmdir__', VariableType.Function, BuiltinFunction("__intern_os_rmdir__", None, builtin_os_rmdir)), ('__intern_os_scandir__', VariableType.Function, BuiltinFunction("__intern_os_scandir__", None, builtin_os_scandir)), + ('__intern_os_get_terminal_size__', VariableType.Function, BuiltinFunction("__intern_os_get_terminal_size__", None, builtin_os_get_terminal_size)), ('__intern_clear__', VariableType.Function, BuiltinFunction("__intern_clear__", None, builtin_clear)), ('__intern_quit__', VariableType.Function, BuiltinFunction("__intern_quit__", None, builtin_quit)), diff --git a/repl/repl.py b/repl/repl.py index 4790ad7..3494cf5 100644 --- a/repl/repl.py +++ b/repl/repl.py @@ -35,9 +35,9 @@ def __init__(self, paraCode): elif paraCode.release_stage == "stable": color = "\033[92m" self.welcome_message = f""" -{"----- P a r a C o d e -----".center(os.get_terminal_size().columns).rstrip()} -{color + (paraCode.release_stage.upper() + " v" + paraCode.version).center(os.get_terminal_size().columns).rstrip() + LogColor.Default} -""" + ----- P a r a C o d e ----- + {color + (paraCode.release_stage.upper() + " v" + paraCode.version) + LogColor.Default} + """ try: from requests import get @@ -45,26 +45,36 @@ def __init__(self, paraCode): if "tag_name" not in latest_version.json() or latest_version.json()["tag_name"] < paraCode.version: # Using unstable and/or development/beta version self.welcome_message += LogColor.Warning + """ -You are using a possibly unstable version! If something doesn't work correctly, that is probably why.""" + LogColor.Default + You are using a possibly unstable + version! If something doesn't work + correctly, that is probably why.""" + LogColor.Default elif latest_version.json()["tag_name"] > paraCode.version: # Update available import datetime self.welcome_message += LogColor.Warning + """ -Version {} is available to update to! It was released {}. Download it from GitHub for new features and bug fixes.""".format(latest_version.json()["tag_name"], "on " + datetime.datetime.strptime(latest_version.json()["published_at"], "%Y-%m-%dT%H:%M:%SZ").strftime('%A %b %d, %Y at %X')) + LogColor.Default + Version {} is available to update + to! It was released {}. + Download it from GitHub for new + features and bug fixes.""".format(latest_version.json()["tag_name"], "on " + datetime.datetime.strptime(latest_version.json()["published_at"], "%Y-%m-%dT%H:%M:%SZ").strftime('%A %b %d, %Y at %X')) + LogColor.Default except: # Error occured (connection failed, couldn't find any releases, etc.) pass - + + # TODO: Check if the user has used ParaCode before. self.welcome_message += """ + + Welcome to ParaCode Rewrite + (codenamed Peaches). + Let's get started! To learn more about ParaCode, type one of the following: {} - """.format('\n '.join(map(lambda key: "{}-- {}".format(key.ljust(16), self._walkthrough_messages[key][0]), - self._walkthrough_messages))) - + """.format('\n '.join(map(lambda key: "{}-- {}".format(key.ljust(16), self._walkthrough_messages[key][0]), self._walkthrough_messages))) + + self.paraCode = paraCode self.interpreter = Interpreter(SourceLocation(Repl.REPL_FILENAME)) @@ -134,14 +144,12 @@ def accept_input(self): return elif trimmed in self._walkthrough_messages or (trimmed.endswith(".md") and trimmed.replace(".md", "", -1) in self._walkthrough_messages) or (trimmed.endswith(".md/") and trimmed.replace(".md/", "", -1) in self._walkthrough_messages): print( - self._walkthrough_messages[trimmed][1].replace('```\n', '').replace('```javascript\n', '').replace('```js\n', '').replace('`', - '')) + self._walkthrough_messages[trimmed][1].replace('```\n', '').replace('```javascript\n', '').replace('```js\n', '').replace('`', '')) return - elif trimmed == "doc" or trimmed == "docs" or trimmed == "walkthrough" or trimmed == "walkthroughs": + elif trimmed == "doc" or trimmed == "docs" or trimmed == "documentation" or trimmed == "documentations" or trimmed == "walkthrough" or trimmed == "walkthroughs": print(""" - {}""".format('\n '.join(map(lambda key: "{}-- {}".format(key.ljust(16), self._walkthrough_messages[key][0]), - self._walkthrough_messages)))) + {}""".format('\n '.join(map(lambda key: "{}-- {}".format(key.ljust(16), self._walkthrough_messages[key][0]), self._walkthrough_messages)))) return (brace_counter, bracket_counter, paren_counter, comment_type) = self.count_continuation_tokens(line) diff --git a/std/os.para b/std/os.para index dd5300b..3e80f7f 100644 --- a/std/os.para +++ b/std/os.para @@ -56,4 +56,8 @@ let os = Type.extend({ func scandir(_, path=".") { return __intern_os_scandir__(path); } + func get_terminal_size(_) { + let size = __intern_os_get_terminal_size__(); + return IntVector2.new(size[0], size[1]); + } }); diff --git a/std/types/str.para b/std/types/str.para index 93b17bd..81d6a6d 100644 --- a/std/types/str.para +++ b/std/types/str.para @@ -7,8 +7,8 @@ let Str = Array.extend({ func __mul__(self, value) { let str = ""; while value { - str = self.append(str); - value -= 1; + str = self.append(str); + value -= 1; } return str; } @@ -38,7 +38,7 @@ let Str = Array.extend({ return self.find(value) == self.len() - value.len(); } - func replace(self, old, new, count=1) { + func replace(self, old, new, count=-1) { return __intern_str_replace__(self._value, old._value, new._value, count); } @@ -53,6 +53,13 @@ let Str = Array.extend({ func totitle(self) { return __intern_str_totitle__(self._value); } + + func center(self, width, fillchar=" ") { + return __intern_str_center__(self._value, width, fillchar); + } + func color(_, num) { + return __intern_get_color__(num) + self; + } func __construct__(self, value) { self._value = value;