Skip to content

Commit

Permalink
Merge pull request #181 from nbuilding/develop
Browse files Browse the repository at this point in the history
N `v1.3.0`
  • Loading branch information
SheepTester authored Jul 10, 2021
2 parents 03a7cf4 + c07208b commit fead436
Show file tree
Hide file tree
Showing 41 changed files with 1,792 additions and 306 deletions.
27 changes: 26 additions & 1 deletion examples/test.n
Original file line number Diff line number Diff line change
@@ -1,2 +1,27 @@
print
import times

let test1 = [] -> cmd[str] {
let _ = times.sleep(1000)!
print("1s")
return "one second later"
}

let test2 = [] -> cmd[str] {
let _ = times.sleep(2000)!
print("2s")
return "two seconds later"
}

let test = [] -> cmd[()] {
let test1Done = parallel(test1())!
let test2Done = parallel(test2())!
print("0s")

let test2Result = test2Done!
let test1Result = test1Done!
let test1Result2 = test1Done!

print({ test2Result: test2Result; test1Result: test1Result; test1Result2: test1Result2 })
}

let pub main = test()
22 changes: 12 additions & 10 deletions python/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
## Python development instructions

Your command line's working directory should be inside the `python/` folder.

Windows: (You may have to do `Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser` first.)

Git Bash users should do `source .venv/Scripts/activate`.

```bat
py -m venv .venv
.\.venv\Scripts\activate
py -m pip install -r python/requirements.txt
py -m pip install -r requirements.txt
py python/n.py --file python/run.n
py n.py --file run.n
deactivate
```
Expand All @@ -19,9 +21,9 @@ Everywhere else:
```sh
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -r python/requirements.txt
python3 -m pip install -r requirements.txt

python3 python/n.py --file python/run.n
python3 n.py --file run.n

deactivate
```
Expand All @@ -40,9 +42,9 @@ python python/n.py

## `requirements.txt`

- Save to requirements.txt: `python3 -m pip freeze > python/requirements.txt` (Windows: `py -m pip freeze | Out-File -Encoding UTF8 python/requirements.txt`)
- Save to requirements.txt: `python3 -m pip freeze > requirements.txt` (Windows: `py -m pip freeze | Out-File -Encoding UTF8 requirements.txt`)

- Load from requirements.txt `pip install -r python/requirements.txt`
- Load from requirements.txt `pip install -r requirements.txt`

## Bundle

Expand All @@ -55,8 +57,8 @@ pyinstaller -y --add-data="syntax.lark;." n.py
Windows users should use `py`, and everyone else should use `python3`.

```sh
# Test syntax
python -m unittest parse_test.py
# Test syntax and type/value assertions
N_ST_DEBUG=dev python -m unittest parse_test.py type_check_test.py
```

## Formatting
Expand All @@ -65,8 +67,8 @@ We conform to the [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide

```sh
# Lint
pylint --disable=all --enable=F,E,unreachable,duplicate-key,unnecessary-semicolon,global-variable-not-assigned,unused-variable,binary-op-exception,bad-format-string,anomalous-backslash-in-string,bad-open-mode,dangerous-default-value **/*.py
pylint --disable=all --enable=F,E,unreachable,duplicate-key,unnecessary-semicolon,global-variable-not-assigned,unused-variable,binary-op-exception,bad-format-string,anomalous-backslash-in-string,bad-open-mode,dangerous-default-value ../**/*.py

# Autoformatting
black python/
black .
```
22 changes: 12 additions & 10 deletions python/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,39 +36,41 @@ def get_lines(self, start, end):
def get_text(self):
return "\n".join(self.lines)

def display(self, start_line, start_col, end_line, end_col, color=Fore.RED):
def display(
self, start_line, start_col, end_line, end_col, color=Fore.RED, underline=True
):
output = []
if start_line == end_line:
line = self.get_line(start_line)
output.append(
f"{Fore.CYAN}{start_line:>{self.line_num_width}} | {Style.RESET_ALL}{line}"
)
output.append(
" " * (self.line_num_width + 2 + start_col)
+ color
+ "^" * (end_col - start_col)
+ Style.RESET_ALL
)
if underline:
output.append(
" " * (self.line_num_width + 2 + start_col)
+ f"{color + '^' * (end_col - start_col) if underline else ''}"
+ Style.RESET_ALL
)
else:
for line_num, line in enumerate(
self.get_lines(start_line, end_line), start=start_line
):
if line_num == start_line:
line = (
line[: start_col - 1]
+ Fore.RED
+ f"{color if underline else ''}"
+ line[start_col - 1 :]
+ Style.RESET_ALL
)
elif line_num == end_line:
line = (
Fore.RED
f"{color if underline else ''}"
+ line[: end_col - 1]
+ Style.RESET_ALL
+ line[end_col - 1 :]
)
else:
line = Fore.RED + line + Style.RESET_ALL
line = f"{color if underline else ''}" + line + Style.RESET_ALL
output.append(
f"{Fore.CYAN}{line_num:>{self.line_num_width}} | {Style.RESET_ALL}{line}"
)
Expand Down
2 changes: 1 addition & 1 deletion python/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,4 @@ async def continue_async():
return value

def __str__(self):
return "<function %s>" % display_type(self.arguments, False)
return "[function]"
14 changes: 7 additions & 7 deletions python/imported_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ def compare(self, other):
return self.file == other.file

def __len__(self):
value = 0
for error in self.err:
if isinstance(error, ImportedError):
value += len(error)
else:
value += 1
value = 0
for error in self.err:
if isinstance(error, ImportedError):
value += len(error)
else:
value += 1

return value
return value
63 changes: 58 additions & 5 deletions python/libraries/FileIO.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,61 @@
import os

from os import listdir
from os.path import isfile, join
from aiofile import async_open
from native_types import n_cmd_type, n_maybe_type, yes, none
from native_types import n_cmd_type, n_maybe_type, yes, none, n_list_type


async def write(path, content):
async with async_open(path, "w+") as f:
async with async_open(path, "w+", encoding="utf-8") as f:
await f.write(content)


async def append(path, content):
async with async_open(path, "a+") as f:
await f.write(content)
try:
async with async_open(path, "a+", encoding="utf-8") as f:
await f.write(content)
except:
pass


async def read(path):
try:
async with async_open(path, "r", encoding="utf-8") as f:
return yes(await f.read())
except FileNotFoundError:
except:
return none


async def writeBytes(path, content):
async with async_open(path, "w+", encoding="utf-8") as f:
await f.write("".join([chr(c) for c in content]))


async def appendBytes(path, content):
try:
async with async_open(path, "a+", encoding="utf-8") as f:
await f.write("".join([chr(c) for c in content]))
except:
pass


async def readBytes(path):
try:
async with async_open(path, "rb", encoding="utf-8") as f:
return yes(list(await f.read()))
except:
return none


async def getFiles(path):
can_run = os.environ.get("FILE_ALLOW") == "true"
if not can_run:
return []

return [(isfile(join(path, f)), f) for f in listdir(path)]


def _values():
return {
# write: str -> str -> cmd[()]
Expand All @@ -31,4 +67,21 @@ def _values():
"str",
n_cmd_type.with_typevars([n_maybe_type.with_typevars(["str"])]),
),
"writeBytes": (
"str",
n_list_type.with_typevars(["int"]),
n_cmd_type.with_typevars(["unit"]),
),
"appendBytes": (
"str",
n_list_type.with_typevars(["int"]),
n_cmd_type.with_typevars(["unit"]),
),
"readBytes": (
"str",
n_cmd_type.with_typevars(
[n_maybe_type.with_typevars([n_list_type.with_typevars(["int"])])]
),
),
"getFiles": ("str", n_cmd_type.with_typevars([n_list_type.with_typevars([["bool", "str"]])])),
}
15 changes: 14 additions & 1 deletion python/libraries/SystemIO.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import asyncio
import os

from concurrent.futures import ThreadPoolExecutor
from native_types import n_cmd_type

Expand All @@ -9,5 +11,16 @@ async def inp(question):
return await asyncio.get_event_loop().run_in_executor(executor, input, question)


def run(command):
can_run = os.environ.get("COMMAND_ALLOW") == "true"
if not can_run:
return False

return os.system(command) == 0


def _values():
return {"inp": ("str", n_cmd_type.with_typevars(["str"]))}
return {
"inp": ("str", n_cmd_type.with_typevars(["str"])),
"run": ("str", n_cmd_type.with_typevars(["bool"])),
}
12 changes: 0 additions & 12 deletions python/libraries/fek.py

This file was deleted.

11 changes: 6 additions & 5 deletions python/libraries/json.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import math

from enums import EnumType, EnumValue
from native_types import n_list_type, n_map_type, NMap, n_maybe_type, yes
Expand Down Expand Up @@ -98,17 +99,16 @@ def parseSafe(string):
except:
return None


def convert_float_to_int(value):
if isinstance(value, float):
if value % 1 == 0:
value = round(value)
elif math.isnan(value) or math.isinf(value):
value = None
elif isinstance(value, dict):
for i in value.keys():
if isinstance(value[i], dict) or isinstance(value[i], list):
value[i] = convert_float_to_int(value[i])
elif isinstance(value[i], float):
if value[i] % 1 == 0:
value[i] = round(value[i])
value[i] = convert_float_to_int(value[i])
elif isinstance(value, list):
for i in range(len(value)):
if isinstance(value[i], dict) or isinstance(value[i], list):
Expand All @@ -119,6 +119,7 @@ def convert_float_to_int(value):

return value


# TODO: Formatting options?
# TODO: Convert NaN and infinities to null, per spec.
def stringify(json_value):
Expand Down
Loading

0 comments on commit fead436

Please sign in to comment.