Skip to content

Commit

Permalink
Merge pull request #3 from KDesp73/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
KDesp73 authored May 27, 2024
2 parents 5e98eef + 97755b8 commit d7c18ed
Show file tree
Hide file tree
Showing 18 changed files with 347 additions and 58 deletions.
75 changes: 75 additions & 0 deletions docs/Design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Design

## Pre-defined methods

- echo "Hello World"
- exit `exit-code` (int)

- run "path/to/script" -- Run external kd script (maybe handled by the preprocessor)

- input() -- Should change
- val(expression) -- Should change
- str(expression) -- Should change

## Blocks

- if-else

```
if condition {
} else {
}
```

- while

```
while condition {
}
```

- do-while

```
do {
} while condition
```

- for

```
for i in 2..3 {
}
```

## Functions

```
# Declaration
func name {
}
# Call
call name
# Call with arguments
call name <- x, 2, 3
# Get return value
a = call name <- 1.3
```

## Preprocessor

```
#import "path/to/file" -- Include methods from file
#assign A 2
#run "path/to/file" -- Run file as script
```

6 changes: 5 additions & 1 deletion examples/comment_in_string.kd
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
echo "hello # world\n"
# This should be removed

echo "hello # world\n" # this should be removed

# This should be removed
13 changes: 10 additions & 3 deletions examples/math.kd
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
func divisionByZero {
a = 4

while a >= 0 {
b = 12 / a
echo "a: ", a, "\n"
echo "b: ", b, "\n"
echo 12, "/", a, "=", b, "\n"

a = a - 1
}
}

func mod_example {
i = 0
while i < 20 {
echo i % 5, "\n"
i = i + 1
}
}

#call mod_example
call divisionByZero
51 changes: 51 additions & 0 deletions examples/menu.kd
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
func home {
echo "Home selected\n"
}

func settings {
echo "Settings selected\n"
}

func about {
echo "About selected\n"
}

func exit {
echo "Exiting...\n"
}

func menu {
echo "1. Home\n"
echo "2. Settings\n"
echo "3. About\n"
echo "4. Exit\n"
echo "> "
choice = val(input())

while choice < 1 | choice > 4 {
echo "> "
choice = val(input())
}

if choice == 4 {
call exit
esc
}


if choice == 1 {
call home
}

if choice == 2 {
call settings
}

if choice == 3 {
call about
}

call menu
}

call menu
2 changes: 1 addition & 1 deletion examples/pyramid.kd
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ func print_pyramid {
}
}

call print_pyramid
call print_pyramid <- x, 2, 3
12 changes: 11 additions & 1 deletion examples/test.kd
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
echo "Hello" echo " World\n"
func test {
a = 1 + 2
echo a, "\n"
echo "Hello\n"

exit a - 2

echo "World\n"
}

call test
38 changes: 29 additions & 9 deletions src/actions.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
import sys
from keywords import KEYWORDS
from state import State
import parser
from errors import Error
from variable import Variable

def do_assign(state: State, active: list):
def run_exit(state: State, active: list):
from expressions import Expression

value = Expression(state, active)[1]

if active[0] and not isinstance(value, int):
Error(state, "expression is not an integer").throw()

if active[0]:
sys.exit(int(value))


def run_assign(state: State, active: list):
from expressions import Expression

id = parser.take_next_alnum(state)
if not parser.take_next(state, '=') or id == "": Error(state, "unknown statement").throw()

if not parser.take_next(state, '=') or id == "":
Error(state, "unknown statement").throw()

if id in KEYWORDS:
Error(state, f"{id} is a reserved keyword").throw()

e = Expression(state, active)
if active[0] or id not in state.variables:
state.variables[id] = e

def do_func_def(state: State):
def run_func_def(state: State):
from expressions import Block

id = parser.take_next_alnum(state)
Expand All @@ -22,19 +42,19 @@ def do_func_def(state: State):
# Skip block inactively
Block(state, [False])

def do_call(state: State, active: list):
def run_call(state: State, active: list):
from expressions import Block

id = parser.take_next_alnum(state)
if id not in state.variables or state.variables[id][0] != Variable.METHOD:
Error(state, "unknown funcroutine").throw()
Error(state, "unknown function").throw()
ret = state.position
state.position = state.variables[id][1]
if active[0]:
Block(state, active)
state.position = ret

def do_if_else(state: State, active: list):
def run_if_else(state: State, active: list):
from expressions import BooleanExpression, Block

b = BooleanExpression(state, active)
Expand All @@ -46,7 +66,7 @@ def do_if_else(state: State, active: list):
Block(state, active)
else: Block(state, [False])

def do_while(state: State, active: list):
def run_while(state: State, active: list):
from expressions import BooleanExpression, Block

local = [active[0]]
Expand All @@ -56,13 +76,13 @@ def do_while(state: State, active: list):
state.position = position_while
Block(state, [False])

def do_echo(state: State, active: list):
def run_echo(state: State, active: list):
from expressions import Expression

while True:
e = Expression(state, active)
if active[0]: print(e[1], end="")
if not parser.take_next(state, ','): return

def do_break(active: list):
def run_break(active: list):
if active[0]: active[0] = False
4 changes: 4 additions & 0 deletions src/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ class RuntimeError(Error):
def __init__(self, state: State, message):
super().__init__(state, message)
self.TAG = "RuntimeError"

def TODO():
ERRO("Not implemented yet")
exit(1)
55 changes: 38 additions & 17 deletions src/expressions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from logger import DEBU
import parser
from state import State
from statements import Statement
from utils import *
from errors import Error, RuntimeError
from variable import Variable
from keywords import KEYWORDS

def BooleanFactor(state: State, active: list):
inv = parser.take_next(state, '!')
Expand Down Expand Up @@ -36,7 +38,7 @@ def BooleanExpression(state: State, active: list):
while parser.take_next(state, '|'): b = b | BooleanTerm(state, active)
return b

def MathFactor(state, active: list):
def MathFactor(state: State, active: list):
m = 0
m_dec = 0
is_dec = False
Expand All @@ -59,19 +61,26 @@ def MathFactor(state, active: list):
elif parser.take_string(state, "val("): # string to num
s = String(state, active)
if active[0]:
if s.isdigit(): m = int(s)
if is_int(s):
m = int(s)
elif is_float(s):
m = float(s)
else: RuntimeError(state, "input not a number").throw()
else: RuntimeError(state, "input is not a number").throw()
if not parser.take_next(state, ')'): Error(state, "missing ')'").throw()
else: # Variables
id = parser.take_next_alnum(state)
if (
id not in state.variables or
(state.variables[id][0] != Variable.INT and state.variables[id][0] != Variable.FLOAT)
):
Error(state, "unknown state.variable").throw()
elif active[0]: m = state.variables[id][1]

if id in KEYWORDS:
Error(state, f"{id} is a reserved keyword").throw()

if id not in state.variables:
Error(state, f"{id} is not defined").throw()

if state.variables[id][0] != Variable.INT and state.variables[id][0] != Variable.FLOAT:
Error(state, f"Variable {id} is not a number").throw()

if active[0]:
m = state.variables[id][1]

return m

Expand All @@ -82,24 +91,35 @@ def MathTerm(state: State, active: list):
m2 = MathFactor(state, active)
if c == '*':
m = m * m2
else:
if m2 == 0:
RuntimeError(state, "Division by zero").throw()
m = m / m2
elif c == '/':
if active[0]:
if m2 == 0:
RuntimeError(state, "Division by zero").throw()
m = m / m2
elif c == '%':
m = m % m2

return m

def MathExpression(state: State, active: list):
c = parser.next(state)

if is_add_op(c):
c = parser.take(state)

m = MathTerm(state, active)
if c == '-': m = -m

if c == '-':
m = -m

while is_add_op(parser.next(state)):
c = parser.take(state)
m2 = MathTerm(state, active)
if c == '+': m = m + m2
else: m = m - m2

if c == '+':
m = m + m2
else:
m = m - m2
return m

def String(state: State, active: list):
Expand All @@ -117,7 +137,8 @@ def String(state: State, active: list):
if not parser.take_next(state, ')'):
Error(state, "missing ')'").throw()
elif parser.take_string(state, "input()"):
if active[0]: s = input()
if active[0]:
s = input()
else:
id = parser.take_next_alnum(state)
if id in state.variables and state.variables[id][0] == Variable.STRING:
Expand Down
Loading

0 comments on commit d7c18ed

Please sign in to comment.