Commit 44114a7d authored by Tom Niget's avatar Tom Niget

Make proper module type and add sys.argv

parent 4e444c27
......@@ -30,4 +30,7 @@ loop: loop.cpp
$(CXX) $(CXXFLAGS) $< -o $@ $(LDLIBS)
naive_fibonacci_fork: naive_fibonacci_fork.cpp
$(CXX) $(CXXFLAGS) $< -o $@ $(LDLIBS)
webserver: webserver.cpp
$(CXX) $(CXXFLAGS) $< -o $@ $(LDLIBS)
\ No newline at end of file
......@@ -26,18 +26,22 @@ public:
size_t py_len() const { return this->size(); }
void py_print(std::ostream &s) const {
void py_repr(std::ostream &s) const {
s << '[';
if (this->size() > 0) {
print_to(this->operator[](0), s);
repr_to(this->operator[](0), s);
for (size_t i = 1; i < this->size(); i++) {
s << ", ";
print_to(this->operator[](i), s);
repr_to(this->operator[](i), s);
}
}
s << ']';
}
void py_print(std::ostream &s) const {
py_repr(s);
}
PyList<T> operator+(const PyList<T> &other) const {
std::vector<T> v;
v.reserve(this->size() + other.size());
......
......@@ -9,6 +9,17 @@
#include <ostream>
#include <typon/typon.hpp>
#include "str.hpp"
template <typename T>
concept Printable = requires(const T &x, std::ostream &s) {
{ print_to(x, s) } -> std::same_as<void>;
};
template <typename T>
concept Reprable = requires(const T &x, std::ostream &s) {
{ repr_to(x, s) } -> std::same_as<void>;
};
template <typename T>
concept Streamable = requires(const T &x, std::ostream &s) {
......@@ -16,6 +27,7 @@ concept Streamable = requires(const T &x, std::ostream &s) {
};
template <Streamable T> void print_to(const T &x, std::ostream &s) { s << x; }
template <Streamable T> void repr_to(const T &x, std::ostream &s) { s << x; }
template <typename T>
concept FunctionPointer =
......@@ -23,11 +35,16 @@ concept FunctionPointer =
std::is_function_v<std::remove_pointer_t<T>>;
template <Streamable T>
requires(FunctionPointer<T>)
void print_to(const T &x, std::ostream &s) {
requires(FunctionPointer<T>)
void repr_to(const T &x, std::ostream &s) {
s << "<function at 0x" << std::hex << (size_t)x << ">";
}
template <>
void repr_to(const PyStr &x, std::ostream &s) {
s << '"' << x << '"';
}
template <typename T>
concept PyPrint = requires(const T &x, std::ostream &s) {
{ x.py_print(s) } -> std::same_as<void>;
......@@ -38,9 +55,23 @@ template <PyPrint T> void print_to(const T &x, std::ostream &s) {
}
template <typename T>
concept Printable = requires(const T &x, std::ostream &s) {
{ print_to(x, s) } -> std::same_as<void>;
concept PyRepr = requires(const T &x, std::ostream &s) {
{ x.py_repr(s) } -> std::same_as<void>;
};
template <PyRepr T> void repr_to(const T &x, std::ostream &s) {
x.py_repr(s);
}
template <Printable T>
void print_to(const std::shared_ptr<T> &x, std::ostream &s) {
print_to(*x, s);
}
template <Printable T>
void repr_to(const std::shared_ptr<T> &x, std::ostream &s) {
repr_to(*x, s);
}
/*
template <Printable T, Printable... Args>
typon::Task<void> print(T const &head, Args const &...args) {
......
......@@ -10,10 +10,18 @@
using namespace std::literals;
template <typename T> std::string str(const T &x) {
using PyStr = std::string;
template <typename T> PyStr str(const T &x) {
std::stringstream s;
print_to(x, s);
return s.str();
}
template <typename T> PyStr repr(const T &x) {
std::stringstream s;
repr_to(x, s);
return s.str();
}
#endif // TYPON_STR_HPP
......@@ -6,13 +6,19 @@
#define TYPON_SYS_HPP
#include <iostream>
#include "builtins.hpp"
namespace py_sys {
struct sys_t {
static constexpr auto &stdin = std::cin;
static constexpr auto &stdout = std::cout;
static constexpr auto &stderr = std::cerr;
PyObj<PyList<PyStr>> argv;
} all;
auto& get_all() {
return all;
}
} // namespace py_sys
#endif // TYPON_SYS_HPP
stdout: CppType["auto&"]
argv: list[str]
\ No newline at end of file
# coding: utf-8
import sys
BACKLOG = 1024
PORT = 8000
if __name__ == "__main__":
print(sys.argv)
\ No newline at end of file
......@@ -42,7 +42,10 @@ class BlockVisitor(NodeVisitor):
from transpiler.phases.emit_cpp.function import FunctionVisitor
yield from FunctionVisitor(self.scope, CoroutineMode.TASK).emit_block(node.scope, block())
yield "int main() { root().call(); }"
yield "int main(int argc, char* argv[]) {"
yield "py_sys::all.argv = pyobj<PyList<PyStr>>(std::vector<PyStr>(argv, argv + argc));"
yield "root().call();"
yield "}"
return
yield "struct {"
......
......@@ -17,7 +17,7 @@ class ModuleVisitor(BlockVisitor):
yield ""
else:
yield from self.import_module(alias.name)
yield f'auto& {alias.asname or alias.name} = py_{alias.name}::all;'
yield f'auto& {alias.asname or alias.name} = py_{alias.name}::get_all();'
def import_module(self, name: str) -> Iterable[str]:
yield f'#include "python/{name}.hpp"'
......@@ -28,7 +28,7 @@ class ModuleVisitor(BlockVisitor):
else:
yield from self.import_module(node.module)
for alias in node.names:
yield f"auto& {alias.asname or alias.name} = py_{node.module}::all.{alias.name};"
yield f"auto& {alias.asname or alias.name} = py_{node.module}::get_all().{alias.name};"
def visit_Expr(self, node: ast.Expr) -> Iterable[str]:
if isinstance(node.value, ast.Str):
......
import ast
import dataclasses
from dataclasses import dataclass
from transpiler.phases.typing.common import ScoperVisitor
from transpiler.phases.typing.expr import ScoperExprVisitor
from transpiler.phases.typing.class_ import ScoperClassVisitor
from transpiler.phases.typing.scope import VarDecl, VarKind, ScopeKind
from transpiler.phases.typing.types import BaseType, TypeVariable, FunctionType, IncompatibleTypesError, TY_MODULE, \
Promise, TY_NONE, PromiseKind, TupleType, UserType, TypeType
from transpiler.phases.typing.types import BaseType, TypeVariable, FunctionType, IncompatibleTypesError, \
Promise, TY_NONE, PromiseKind, TupleType, UserType, TypeType, ModuleType
@dataclass
......@@ -21,13 +22,14 @@ class ScoperBlockVisitor(ScoperVisitor):
def visit_Import(self, node: ast.Import):
for alias in node.names:
self.scope.vars[alias.asname or alias.name] = VarDecl(VarKind.LOCAL, None)
mod = self.scope.get(alias.name, VarKind.MODULE)
self.scope.vars[alias.asname or alias.name] = dataclasses.replace(mod, kind=VarKind.LOCAL)
def visit_ImportFrom(self, node: ast.ImportFrom):
module = self.scope.get(node.module)
module = self.scope.get(node.module) # TODO: VarKind.MODULE ?
if not module:
raise NameError(node.module)
if module.type is not TY_MODULE:
if not isinstance(module.type, ModuleType):
raise IncompatibleTypesError(f"{node.module} is not a module")
for alias in node.names:
thing = module.val.get(alias.name)
......
......@@ -15,6 +15,7 @@ class VarKind(Enum):
"""`nonlocal xxx`"""
SELF = 4
OUTER_DECL = 5
MODULE = 6
class VarType:
......@@ -70,12 +71,12 @@ class Scope:
"""Declares a local variable"""
self.vars[name] = VarDecl(VarKind.LOCAL, type)
def get(self, name: str) -> Optional[VarDecl]:
def get(self, name: str, kind: VarKind = VarKind.LOCAL) -> Optional[VarDecl]:
"""
Gets the variable declaration of a variable in the current scope or any parent scope.
"""
if (res := self.vars.get(name)) and res.kind == VarKind.LOCAL:
if (res := self.vars.get(name)) and res.kind == kind:
return res
if self.parent is not None:
return self.parent.get(name)
return self.parent.get(name, kind)
return None
......@@ -214,6 +214,10 @@ class TypeOperator(BaseType, ABC):
def to_list(self) -> List["BaseType"]:
return [self, *self.args]
@dataclass
class ModuleType(TypeOperator):
pass
class FunctionType(TypeOperator):
def __init__(self, args: List[BaseType], ret: BaseType):
......@@ -270,7 +274,7 @@ TY_STR = TypeOperator([], "str")
TY_BOOL = TypeOperator([], "bool")
TY_COMPLEX = TypeOperator([], "complex")
TY_NONE = TypeOperator([], "NoneType")
TY_MODULE = TypeOperator([], "module")
#TY_MODULE = TypeOperator([], "module")
TY_VARARG = TypeOperator([], "vararg")
TY_SELF = TypeOperator([], "Self")
TY_SELF.gen_sub = lambda this, typevars, _: this
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment