Skip to content

Commit

Permalink
Added eval, to_int, to_str
Browse files Browse the repository at this point in the history
  • Loading branch information
NexInfinite committed Aug 25, 2021
1 parent caa0c01 commit c0dc819
Show file tree
Hide file tree
Showing 17 changed files with 208 additions and 31 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,26 @@ To do this change:<br>
<br>to<br>
![img_1.png](images/syntax_2.png)

### Eval
There are things in this language that you can only do in python. If you need
to run python eval then you can do:
```
var test = `print("This is from python")`
eval(test)
```
Which will output<br>
![img.png](images/eval_1.png)
<br>
This is all editable in the editable.py file.


# Todo
There are a couple of builtin function that have not been created yet, this will be
done in the future.
- [ ] to_str
- [ ] to_int
- [x] to_str
- [x] to_int
- [x] eval
- [ ] make builtins easier to add

# What are the plans?
I am planning to allow more control, for example a way to change all grammar rules
Expand Down
Binary file added images/eval_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified whython/__pycache__/lexer.cpython-39.pyc
Binary file not shown.
6 changes: 4 additions & 2 deletions whython/docs/todo.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ DONE:
run
length
randint
TODO:
to_str
to_int
to_int
use python code
TODO:
make builtins easier
Binary file modified whython/editable_/__pycache__/editable.cpython-39.pyc
Binary file not shown.
4 changes: 4 additions & 0 deletions whython/editable_/editable.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
# changing the below to
# global_symbol_table.set("shout", BuiltInFunction("print"))
# will make shout("value") work instead of print("value")
# If you want an example of what each of this functions do go to values/value_builtinfunc.py and find the correct function.
global_symbol_table.set("print", BuiltInFunction("print"))
global_symbol_table.set("input", BuiltInFunction("input"))
global_symbol_table.set("input_int", BuiltInFunction("input_int"))
Expand All @@ -92,6 +93,9 @@
global_symbol_table.set("run", BuiltInFunction("run"))
global_symbol_table.set("len", BuiltInFunction("len"))
global_symbol_table.set("randint", BuiltInFunction("randint"))
global_symbol_table.set("to_str", BuiltInFunction("to_str"))
global_symbol_table.set("to_int", BuiltInFunction("to_int"))
global_symbol_table.set("eval", BuiltInFunction("pyeval"))

# *###################
# * GRAMMAR RULES
Expand Down
26 changes: 26 additions & 0 deletions whython/examples/eval.whython
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# run("examples/eval")

var test_1 = `input("What's your name? ")`
var name = eval(test_1)
print(name)

var test_2 = `
print("test_2")
`
print("\n")
eval(test_2)

var test_3 = `
for i in range(10):
print(f"hello, test_3! {i}")
`
print("\n")
eval(test_3)

var test_4 = `
def test_4():
print("Test 4 is wrapped in a function!")
test_4()
`
print("\n")
eval(test_4)
Binary file not shown.
Binary file not shown.
Binary file not shown.
28 changes: 28 additions & 0 deletions whython/execute/execute_pyeval.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# *###################
# * IMPORTS
# *###################

from values.value_string import String
from runtime_results import RTResult
from errors import RTError


# *###################
# * PYTHON EVAL
# *###################

def execute_pyeval_func(self, exec_ctx):
code = exec_ctx.symbol_table.get("code")
try:
# code = compile(code.value, "script", "exec")
try:
response = eval(code.value)
except:
response = exec(code.value)
return RTResult().success(String(response))
except Exception as e:
return RTResult().failure(RTError(
self.pos_start, self.pos_end,
f"The code could not be evaluated. \n\n{e}",
exec_ctx
))
25 changes: 25 additions & 0 deletions whython/execute/execute_to_int.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# *###################
# * IMPORTS
# *###################

from values.value_string import String
from values.value_number import Number
from runtime_results import RTResult
from errors import RTError


# *###################
# * TO INTEGER
# *###################

def execute_to_int_func(self, exec_ctx):
value = exec_ctx.symbol_table.get("value")

if not isinstance(value, String):
return RTResult().failure(RTError(
self.pos_start, self.pos_end,
f"The first argument must be a string.",
exec_ctx
))

return RTResult().success(Number(int(value.value)))
15 changes: 15 additions & 0 deletions whython/execute/execute_to_str.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# *###################
# * IMPORTS
# *###################

from values.value_string import String
from runtime_results import RTResult


# *###################
# * TO STRING
# *###################

def execute_to_str_func(self, exec_ctx):
value = exec_ctx.symbol_table.get("value")
return RTResult().success(String(str(value)))
19 changes: 18 additions & 1 deletion whython/lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ def make_tokens(self):
tokens.append(self.make_number())
elif self.current_char in LETTERS_DIGITS:
tokens.append(self.make_identifier())
elif self.current_char == "`":
tokens.append(self.make_code_block())
elif self.current_char == '"':
tokens.append(self.make_string())
elif self.current_char == "!":
Expand Down Expand Up @@ -189,10 +191,25 @@ def make_string(self):
self.advance()
return Token(TT_STRING, final_string, pos_start, self.pos)

def make_code_block(self):
final_string = ""
pos_start = self.pos.copy()
self.advance()

while self.current_char is not None and self.current_char != "`":
if self.current_char == ";":
final_string += "\n"
else:
final_string += self.current_char
self.advance()

self.advance()
return Token(TT_STRING, final_string, pos_start, self.pos)

def skip_comment(self):
self.advance()

while self.current_char != "\n":
while self.current_char != "\n" and self.current_char is not None:
self.advance()

self.advance()
19 changes: 10 additions & 9 deletions whython/shell.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import run as whython

while True:
text = input("whython > ")
if text.strip() == "": continue
result, error = whython.run("<stdin>", text)
def main():
while True:
text = input("whython > ")
if text.strip() == "": continue
result, error = whython.run("<stdin>", text)

if error: print(error.as_string())
elif result:
if len(result.elements) == 1:
if error: print(error.as_string())
elif result:
for element in result.elements:
try:
if element.value is not None:
print(element)
except AttributeError:
pass
else:
print(repr(result))

if __name__ == "__main__":
main()
Binary file modified whython/values/__pycache__/value_builtinfunc.cpython-39.pyc
Binary file not shown.
78 changes: 61 additions & 17 deletions whython/values/value_builtinfunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
from execute.execute_extend import execute_extend_func
from execute.execute_len import execute_len_func
from execute.execute_run import execute_run_func
from execute.execute_to_str import execute_to_str_func
from execute.execute_to_int import execute_to_int_func
from execute.execute_pyeval import execute_pyeval_func

from runtime_results import RTResult

Expand Down Expand Up @@ -267,20 +270,61 @@ def execute_randint(self, exec_ctx):
return execute_randint_func(self, exec_ctx)
execute_randint.arg_names = ["from", "to"]

BuiltInFunction.print = BuiltInFunction("print")
BuiltInFunction.print_ret = BuiltInFunction("print_ret")
BuiltInFunction.input = BuiltInFunction("input")
BuiltInFunction.input_int = BuiltInFunction("input_int")
BuiltInFunction.clear = BuiltInFunction("clear")
BuiltInFunction.exit = BuiltInFunction("exit")
BuiltInFunction.update_value = BuiltInFunction("update_value")
BuiltInFunction.is_num = BuiltInFunction("is_num")
BuiltInFunction.is_str = BuiltInFunction("is_str")
BuiltInFunction.is_list = BuiltInFunction("is_list")
BuiltInFunction.is_func = BuiltInFunction("is_func")
BuiltInFunction.append = BuiltInFunction("append")
BuiltInFunction.pop = BuiltInFunction("pop")
BuiltInFunction.extend = BuiltInFunction("extend")
BuiltInFunction.run = BuiltInFunction("run")
BuiltInFunction.len = BuiltInFunction("len")
BuiltInFunction.randint = BuiltInFunction("randint")
def execute_to_str(self, exec_ctx):
"""
Convert a number or list to string.
Example 1:
var list = [1, 2, 3]
var list_str = to_str(list)
print(list_str) -> 1, 2, 3
# This is very similar to just printing the list but you can also concat differently.
# Notice the comma on the second output
print(list_str + "test") -> 1, 2, 3test
print(list + "test") -> 1, 2, 3, test
Example 2:
var number = 1
var number_str = to_str(number)
var number_str_2 = number_str + 2 - > Illegal operator
var number_str_2 = number_str + "2" -> 12
:arg value: The thing you want to cast to a string
:return: The string version of the value
"""
return execute_to_str_func(self, exec_ctx)
execute_to_str.arg_names = ["value"]

def execute_to_int(self, exec_ctx):
"""
Convert a string to an int.
Example:
var string = "2"
var string_num = to_int(string)
print(string_num + 2) -> 4
:arg value: A string you want to convert to an integer.
:return: The integer version of the value
"""
return execute_to_int_func(self, exec_ctx)
execute_to_int.arg_names = ["value"]

def execute_pyeval(self, exec_ctx):
"""
Eval the value in python.
Example 1:
var test = `for i in range(10): print(i)`
eval(test) -> 0 1 2 3 4 5 6 7 8 9
Example 2:
var test = `for i in range(10):
print(i)`
eval(test) -> 0 1 2 3 4 5 6 7 8 9
Example 3:
var test = `"hello"`
var response = eval(test)
print(response) -> "hello"
Example 4:
var test = `input("What's your name? ")`
var name = eval(test) -? Julian
print(name) -> Julian
:arg code: The code you want to evaluate.
:return: The response, if any, of the eval.
"""
return execute_pyeval_func(self, exec_ctx)
execute_pyeval.arg_names = ["code"]

0 comments on commit c0dc819

Please sign in to comment.