Skip to content

Commit

Permalink
First update!
Browse files Browse the repository at this point in the history
Everything you need (for now)
  • Loading branch information
NexInfinite committed Aug 12, 2021
1 parent ce18477 commit 77e3ce8
Show file tree
Hide file tree
Showing 114 changed files with 3,219 additions and 4 deletions.
49 changes: 45 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,46 @@
# Coming soon
> Please stand by!
# What is whython?
> An almost fully customizable language made in python!
# whython
An almost fully customizable language made in python!
Whython is a project language, the idea of it is that anyone can download
and edit the language to make it suitable to what they want. This could be
a change that makes it more like a language they know; a change that makes
it easier for new people to learn the language; or even a change that makes
it into a shitpost, it doesn't matter. You have the control!

# What can whython do?
At the point of writing this (the first main push) you can change anything in the
file [editable.py](whython/editable_/editable.py). This means you can change all the
keywords (except = - / * ^) and all the builtin function names.
### Keywords
For example, you may not like creating a variable like this:
```
var x = 10
```
and so you can change `KEYWORDS_DICT["var"]` to "let" and create a variable like this:
```
let x = 10
```
![img.png](images/keywords_dict_1.png)
<br>to<br>
![img_1.png](images/keywords_dict_2.png)

### Builtin functions
You may hate calling print like this:
```
print("Hello, World!")
```
and so you can change the global_symbol_table to be "shout" and print like this:
```
shout("Hello, World!")
```
![img.png](images/builtins_1.png)
<br>to<br>
![img_1.png](images/builtins_2.png)

# What are the plans?
I am planning to allow more control, for example a way to change all grammar rules
and also easily add builtins (right now its kind of tedious).

# How can I contribute?
Either create a request on GitHub or message me on discord `Nexin#0001` to ask for
new features.
Binary file added images/builtins_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 added images/builtins_2.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 added images/keywords_dict_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 added images/keywords_dict_2.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 added whython/__pycache__/constants.cpython-39.pyc
Binary file not shown.
Binary file added whython/__pycache__/context.cpython-39.pyc
Binary file not shown.
Binary file added whython/__pycache__/errors.cpython-39.pyc
Binary file not shown.
Binary file added whython/__pycache__/interpreter.cpython-39.pyc
Binary file not shown.
Binary file added whython/__pycache__/lexer.cpython-39.pyc
Binary file not shown.
Binary file added whython/__pycache__/parser.cpython-39.pyc
Binary file not shown.
Binary file added whython/__pycache__/position.cpython-39.pyc
Binary file not shown.
Binary file added whython/__pycache__/run.cpython-39.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added whython/__pycache__/symbol_table.cpython-39.pyc
Binary file not shown.
Binary file added whython/__pycache__/tokens.cpython-39.pyc
Binary file not shown.
14 changes: 14 additions & 0 deletions whython/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# *###################
# * IMPORTS
# *###################

import string

# *###################
# * CONSTANTS
# *###################

DIGITS = '0123456789'
LETTERS = string.ascii_letters
LETTERS_DIGITS = LETTERS + DIGITS
QUOTES = "'\""
10 changes: 10 additions & 0 deletions whython/context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# *###################
# * CONTEXT
# *###################

class Context:
def __init__(self, display_name, parent=None, parent_entry_pos=None):
self.display_name = display_name
self.parent = parent
self.parent_entry_pos = parent_entry_pos
self.symbol_table = None
26 changes: 26 additions & 0 deletions whython/docs/builtins.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
DONE:
print
input
input_int
clear
exit
update_value
is_num
is_string
is_list
is_function
append
pop
extend
run
length
randint
TODO:
to_str
to_int
run("../helloworld.whython")
run("../guesser.whython")
run("../errortest.whython")
run("../changelist.whython")
FIXME:
executes
63 changes: 63 additions & 0 deletions whython/docs/grammar.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
(LESS)

statements : NEWLINE* statement (NEWLINE+ statement)* NEWLINE*

statement : KEYWORD:return expr?
: KEYWORD:continue
: KEYWORD:break
: expr

expr : KEYWORD:var IDENTIFIER EQ expr
: comp_expr ((KEYWORD:and | KEYWORD:or | KEYWORD:not) comp_expr)*

comp_expr : NOT comp_expr
: arith_expr ((EE | LT | LTE | GT | GTE) arith_expr)*

arith_expr : term ((PLUS | MINUS) term)*

term : factor ((MUL | DIV) factor)*

factor : (PLUS | MINUS) factor
: power

exponent : call (EXPONENT factor)*

call : atom (LPAREN (expr (COMMA expr)*)? RPAREN)?

atom : INT | FLOAT | STRING | IDENTIFIER
: LPAREN expr RPAREN
: list_expr
: if_expr
: for_expr
: while_expr
: func_def

list_expr : LSQUARE (expr (COMMA expr)*)? RSQUARE

if_expr : KEYWORD:if expr KEYWORD:then
(statement if_expr_b | if_expr_c?)
| (NEWLINE statements KEYWORD:end if_expr_b | if_expr_c)

if_expr_b : KEYWORD:elif expr KEYWORD:then
(statement if_expr_b | if_expr_c?)
| (NEWLINE statements KEYWORD:end if_expr_b | if_expr_c)

if_expr_c : KEYWORD:else
statement
| (NEWLINE statements KEYWORD:end)

for_expr : KEYWORD:for KEYWORD:var IDENTIFIER EQ expr KEYWORD:to expr
(KEYWORD:STEP expr)? KEYWORD:then
statement
| (NEWLINE statements KEYWORD:end)

while_expr : KEYWORD:while expr KEYWORD:then
statement
| (NEWLINE statements KEYWORD:end)

func_def : KEYWORD:func IDENTIFIER?
LPAREN (IDENTIFIER (COMMA IDENTIFIER)*)? RPAREN
(ARROW expr)
| (NEWLINE statements KEYWORD:end)

(MORE)
Binary file not shown.
88 changes: 88 additions & 0 deletions whython/editable_/editable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# *###################
# * IMPORTS
# *###################

from symbol_table import SymbolTable

from values.value_builtinfunc import BuiltInFunction
from values.value_number import Number

# *###################
# * KEYWORDS
# * YOU CAN EDIT THIS!
# *###################

"""
How to use:
Change the value in the dict (right hand side) to the new value you want it to be.
For example changing
`"var": "var",` to `"var": "let",`
will change
var x = 10 to let x = 10
You cannot change the value to be a value with spaces, for example
"let this be" will not work but "let_this_be" will work!
"""

KEYWORDS_DICT = {
"var": "let",
"and": "and",
"or": "or",
"elif": "elif",
"else": "else",
"if": "if",
"not": "not",
"do": "do",
"for": "for",
"to": "to",
"step": "step",
"while": "while",
"func": "func",
"end": "end",
"return": "return",
"continue": "continue",
"break": "break",
}

# *###################
# * SYMBOL TABLE
# * YOU CAN EDIT THIS!
# *###################

"""
How to use:
Change the value in the first argument of .set()
For example:
global_symbol_table.set("null", Number.null)
->
global_symbol_table.set("nill", Number.null)
This will change the value `null` to `nill` in the command line.
"""

global_symbol_table = SymbolTable()
global_symbol_table.set("null", Number.null)
global_symbol_table.set("true", Number.true)
global_symbol_table.set("false", Number.false)
global_symbol_table.set("pi", Number.pi)

global_symbol_table.set("shout", BuiltInFunction.print)
global_symbol_table.set("input", BuiltInFunction.input)
global_symbol_table.set("input_int", BuiltInFunction.input_int)
global_symbol_table.set("clear", BuiltInFunction.clear)
global_symbol_table.set("exit", BuiltInFunction.exit)
global_symbol_table.set("update_value", BuiltInFunction.update_value)
global_symbol_table.set("is_num", BuiltInFunction.is_num)
global_symbol_table.set("is_str", BuiltInFunction.is_str)
global_symbol_table.set("is_list", BuiltInFunction.is_list)
global_symbol_table.set("is_func", BuiltInFunction.is_func)
global_symbol_table.set("append", BuiltInFunction.append)
global_symbol_table.set("pop", BuiltInFunction.pop)
global_symbol_table.set("extend", BuiltInFunction.extend)
global_symbol_table.set("run", BuiltInFunction.run)
global_symbol_table.set("len", BuiltInFunction.len)
global_symbol_table.set("randint", BuiltInFunction.randint)
63 changes: 63 additions & 0 deletions whython/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# *###################
# * IMPORTS
# *###################

from strings_with_arrows import *

# *###################
# * ERRORS
# *###################

class Error:
def __init__(self, pos_start, pos_end, error_name, details):
self.error_name = error_name
self.details = details
self.pos_start = pos_start
self.pos_end = pos_end

def as_string(self):
result = f"{self.error_name}: {self.details}"
result += f"\nFile {self.pos_start.fn}, line {self.pos_start.ln + 1}"
result += '\n\n' + string_with_arrows(self.pos_start.ftxt, self.pos_start, self.pos_end)
return result

class IllegalCharError(Error):
def __init__(self, pos_start, pos_end, details):
super().__init__(pos_start, pos_end, 'Illegal Character', details)


class ExpectedCharError(Error):
def __init__(self, pos_start, pos_end, details=''):
super().__init__(pos_start, pos_end, 'Expected Character', details)


class InvalidSyntaxError(Error):
def __init__(self, pos_start, pos_end, details=''):
super().__init__(pos_start, pos_end, 'Invalid Syntax', details)

class CastingError(Error):
def __init__(self, pos_start, pos_end, details=''):
super().__init__(pos_start, pos_end, 'Casting Error', details)

class RTError(Error):
def __init__(self, pos_start, pos_end, details, context):
super().__init__(pos_start, pos_end, 'Runtime Error', details)
self.context = context

def as_string(self):
result = self.generate_traceback()
result += f"{self.error_name}: {self.details}"
result += '\n\n' + string_with_arrows(self.pos_start.ftxt, self.pos_start, self.pos_end)
return result

def generate_traceback(self):
result = ""
pos = self.pos_start
ctx = self.context

while ctx:
result = f" >> File {pos.fn}, line {str(pos.ln + 1)}, in {ctx.display_name}\n"
pos = ctx.parent_entry_pos
ctx = ctx.parent

return f"Traceback (most recent call last):\n {result}"
23 changes: 23 additions & 0 deletions whython/examples/guesser.whython
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var number = randint(1, 100)

func winner()
print("This is the winner message!!!")
end

while true do
print("Guess a number between 1 and 100")
var x = input_int()
if x <= 100 and x >= 1 do
if x == number do
print("You got it!")
winner()
break
elif x < number do
print("Too low!")
elif x > number do
print("Too high!")
end
else
print("Number not within range of 1 and 100")
end
end
1 change: 1 addition & 0 deletions whython/examples/hello_world.whython
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print("Hello, World!")
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added whython/execute/__pycache__/execute_pop.cpython-39.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
27 changes: 27 additions & 0 deletions whython/execute/execute_append.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# *###################
# * IMPORTS
# *###################

from values.value_list import List
from values.value_number import Number
from runtime_results import RTResult

from errors import RTError

# *###################
# * APPEND
# *###################

def execute_append_func(self, exec_ctx):
list_ = exec_ctx.symbol_table.get("list")
value = exec_ctx.symbol_table.get("value")

if not isinstance(list_, List):
return RTResult().failure(RTError(
self.pos_start, self.pos_end,
"First argument must be a list",
exec_ctx
))

list_.elements.append(value)
return RTResult().success(Number.null)
16 changes: 16 additions & 0 deletions whython/execute/execute_clear.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# *###################
# * IMPORTS
# *###################

import os

from values.value_number import Number
from runtime_results import RTResult

# *###################
# * PRINT
# *###################

def execute_clear_func(self, exec_ctx):
os.system("cls" if os.name == "nt" else "clear")
return RTResult().success(Number.null)
Loading

0 comments on commit 77e3ce8

Please sign in to comment.