Skip to content

Commit

Permalink
feat: start cosmoc syntax definition (#2)
Browse files Browse the repository at this point in the history
* checkpoint 1

* wip: AST construction from json

* dev: move on parser.cos

* feat: test iter traits

* feat: draft deserializer

* feat: add macro highlighting

* test: review case tests

* feat: refactor Item and Module

* feat: initialize select test

* feat: setup testing

---------

Co-authored-by: seven-mile <[email protected]>
  • Loading branch information
Myriad-Dreamin and seven-mile authored Sep 27, 2024
1 parent 8e46a54 commit 5b409ea
Show file tree
Hide file tree
Showing 48 changed files with 1,025 additions and 490 deletions.
10 changes: 8 additions & 2 deletions Venv.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
function RunCosmo {
node '--enable-source-maps' ./cmd/cosmo/main.js $args
node '--enable-source-maps' ./cmd/cosmo/main.js $args
}

Set-Alias cosmo RunCosmo
Set-Alias cosmo RunCosmo

function RunCosmoPerf {
npx "0x" "--" node '--enable-source-maps' ./cmd/cosmo/main.js $args
}

Set-Alias cosmo-perf RunCosmoPerf
6 changes: 6 additions & 0 deletions docs/cosmo/notes.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

== Features: default type parameters

https://contributors.scala-lang.org/t/generic-defaults-clazz-t-int/4759/11

An important thing to consider is that IIRC, defaults for type parameters prevent type inference for these parameters in TypeScript, which is a pretty big restriction, and may not fly in Scala. Or maybe it’s not so important for the use cases considered, who knows?
4 changes: 4 additions & 0 deletions fixtures/Type/dispatches/HelloWorld.cos-ast
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class T { val x = 1; }
-----
T().x
T(x: T().x).x
17 changes: 15 additions & 2 deletions library/std/src/collections/vec.cos
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

import vectorSys from "@lib/c++/vector"

pub def CppVec(T: Type): Type = vectorSys.std.vector(T)
import stdIter from std.iter

pub class Vec(T: Type) {
pub def CppVec[T]: Type = vectorSys.std.vector(T)

pub class Vec[T] {
var internal: CppVec(T) = CppVec(T)();

def push(self, value: T) = {
Expand All @@ -12,6 +14,17 @@ pub class Vec(T: Type) {
def size(self): usize = {
self.internal.size()
}

def begin(&self): any = self.internal.begin()
def end(&self): any = self.internal.end()

def iter(&self): any = {
stdIter.CppIter[&T, decltype(self.internal.begin())](self.internal.begin(), self.internal.end())
}

def iter_mut(&mut self): any = {
stdIter.CppIterMut[&mut T, decltype(self.internal.begin())](self.internal.begin(), self.internal.end())
}
}

// template <typename T, typename Ctx, typename Cond = void> struct CppVec {
Expand Down
40 changes: 40 additions & 0 deletions library/std/src/iter.cos
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

class CppIter[E, T] {
var curr: T;
var eof: T;

def begin(&self): any = self.curr
def end(&self): any = self.eof
}

impl[E, T<: cstd.Deref[E]] Iter[&E] for CppIter[E, T] {
def next(&mut self): Option[&E] = {
if (self.curr == self.eof) {
Option[&E]::None
} else {
val result = cstd.deref(self.curr);
cstd.inc(self.curr);
Option[&E]::Some(result)
}
}
}

class CppIterMut[E, T] {
var curr: T;
var eof: T;

def begin(&self): any = self.curr
def end(&self): any = self.eof
}

impl[T, E<: cstd.DerefMut[E]] Iter[&mut E] for CppIterMut[E, T] {
def next(&mut self): Option[&mut E] = {
if (self.curr == self.eof) {
Option[&mut E]::None
} else {
var result = cstd.deref_mut(self.curr);
cstd.inc(self.curr);
Option[&mut E]::Some(result)
}
}
}
40 changes: 25 additions & 15 deletions library/std/src/json.cos
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,19 @@ pub class ValueT(T: Type) {
def expectStr(self): String = {
self match {
case ValueT(T).Str(s) => s
case _ => panic("value is not a string");
case _ => {panic("value is not a string");}
}
}

def apply(Ty: Type, &self, index: Ty): ValueT(T) = {
def expectArray(self): vec.Vec(T) = {
self match {
case ValueT(T).Array(arr) => arr
case _ => {panic("value is not an array");}
}
}

// def apply(Ty: Type, &self, index: Ty): ValueT(T) = {
def apply(&self, index: str): ValueT(T) = {
self match {
case ValueT(T).Null => {panic("value is null");}
case ValueT(T).Bool(b) => {panic("value is a boolean");}
Expand All @@ -34,22 +42,22 @@ pub class ValueT(T: Type) {
case ValueT(T).Str(s) => {panic("value is a string");}
case ValueT(T).Array(arr) => {
code("""
if constexpr (std::is_unsigned_v<Ty>) {
return T::pack(arr.internal[index]);
} else {
// if constexpr (std::is_unsigned_v<Ty>) {
// return T::pack(arr.internal[index]);
// } else {
panic("invalid index type for array");
return cosmo_std::json::ValueT<T>::Null_cons();
}
// }
""");
}
case ValueT(T).Object(obj) => {
code("""
if constexpr (std::is_same_v<Ty, cosmo_std::str::String> || std::is_same_v<Ty, std::string>) {
// if constexpr (std::is_same_v<Ty, cosmo_std::str::String> || std::is_same_v<Ty, std::string>) {
return T::pack(obj.internal[index]);
} else {
panic("invalid index type for object");
return cosmo_std::json::ValueT<T>::Null_cons();
}
// } else {
// panic("invalid index type for object");
// return cosmo_std::json::ValueT<T>::Null_cons();
// }
""");
}
}
Expand All @@ -69,13 +77,13 @@ class NlohmannJsonImpl {
// lazy def value: ValueT(Self) = Self.pack(internal);

def parse(content: String): any = {
self.pack(NlohmannJsonImpl(NlohmannJsonValue.parse(content.internal)))
self.pack(&NlohmannJsonImpl(NlohmannJsonValue.parse(content.internal)))
}

def getAs(Ty: Type, self): Ty = self.internal.get(Ty)()
def getAs(Ty: Type, &self): Ty = self.internal.get(Ty)()

// todo: Self != NlohmannJsonImpl...
def pack(j: NlohmannJsonImpl): ValueT(NlohmannJsonImpl) = {
def pack(j: &NlohmannJsonImpl): ValueT(NlohmannJsonImpl) = {
val mTag: c_enum = NlohmannJsonTag(Ref(j.internal));
// stdSys.printf("%d\n".data(), mTag);

Expand Down Expand Up @@ -105,7 +113,9 @@ class NlohmannJsonImpl {
}""");
ValueT(NlohmannJsonImpl).Object(o)
}
case _ => panic("Invalid JSON type ");
case _ => {
panic("Invalid JSON type ");
}
}
}
}
Expand Down
30 changes: 30 additions & 0 deletions library/std/src/memory.cos
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,36 @@ pub class Arc(T: Type) {
// }
}

code("""
namespace cosmo {
template <typename T>
struct ptr {
T *internal;
ptr() : internal(nullptr) {}
ptr(T *p) : internal(p) {}
ptr(T &r) : internal(&r) {}
};
// FIXME: This is a hack to move value to head ptr.
// FIXME: Should be member function of ptr.
template <typename T, typename U>
ptr<T> allocRawPtr(U &&u) {
return ptr<T>{new T(std::forward<U>(u))};
}
} // namespace cosmo
""")

pub class Ptr[T] {
var internal: mmSys.cosmo.ptr(T) = mmSys.cosmo.ptr(T)();

def alloc(t: T): Ptr(T) = {
var res = Ptr(T)();
res.internal = mmSys.cosmo.allocRawPtr(T)(t);
res
}
}

class AtomicOrdering {
case Relaxed
case Consume
Expand Down
10 changes: 10 additions & 0 deletions library/std/src/prelude/core.cos
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import _ from std::str

import std::fmt

trait Iter[T] {
def next(&mut self): Option[T];
}

trait Formatter {
def write(&mut self, s: &str): fmt::Result(());
}
Expand Down Expand Up @@ -86,6 +90,12 @@ impl ToString for str {
}
}

impl ToString for String {
def toString(&self): String = {
self.clone()
}
}

impl ToString for f32 {
def toString(&self): String = {
// cSys
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/str.cos
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ pub class String {
def as_str(&self): &str = {
internal
}

def clone(&self): String = {
String(internal)
}
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
Some(
value = Block(
stmts = List(
Decorate(
lhs = Apply(lhs = Ident(name = "noCore"), rhs = List(), ct = false),
rhs = Semi(semi = None)
),
Import(
path = Select(
lhs = Select(lhs = Ident(name = "std"), rhs = Ident(name = "prelude"), ct = false),
rhs = Ident(name = "core_stage1"),
ct = false
),
dest = Some(value = Ident(name = "_"))
),
Def(
name = Ident(name = "main"),
params = Some(value = List()),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[T().x] => instance T(Opaque(Some(kDefault),None)).x, type: i32, err: ""
[T(x: T().x).x] => instance T(instance T(Opaque(Some(kDefault),None)).x).x, type: i32, err: ""
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[T(x: 1, y: 2) match {
case T(x, y) => x + y
}] => block {
ClassDestruct(ins (class(T))(Integer(1), Integer(2)),class(T),List((var x_56:56 = NoneKind(0)), (var y_57:57 = NoneKind(0))))
var x@52: i32 = var x_56@56: i32 = _
var y@53: i32 = var y_57@57: i32 = _
"+"(var x@52: i32 = _, var y@53: i32 = _)
ClassDestruct(ins (class(T))(Int32(1), Int32(2)),class(T),List((var x_58:58 = NoneKind(0)), (var y_59:59 = NoneKind(0))))
var x@54: i32 = var x_58@58: i32 = _
var y@55: i32 = var y_59@59: i32 = _
"+"(var x@54: i32 = _, var y@55: i32 = _)
}, err: ""
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@
case ValueT(i32).Null => 1
}] => typeMatch (instance ValueT::Null() by ValueT<int32_t>) {
case ValueT::Null => block {
ClassDestruct(ins (class(ValueT::Null))(),class(ValueT::Null),List((var i32_65:65 = NoneKind(0))))
ClassDestruct(ins (class(ValueT::Null))(),class(ValueT::Null),List((var i32_67:67 = NoneKind(0))))
1
}
} else Unreachable, err: "missing case EnumField(class(ValueT::Elem)) when matching ins (class(ValueT::Null))() on class(ValueT<ref(i32)>)"
} else BottomKind(0), err: "missing case EnumField(class(ValueT::Elem)) when matching ins (class(ValueT::Null))() on class(ValueT<ref(i32)>)"
[v1 match {
case ValueT(i32).Null => 1
}] => typeMatch (val v1@54: ValueT::Null = instance ValueT::Null() by ValueT<int32_t>) {
}] => typeMatch (val v1@56: ValueT::Null = instance ValueT::Null() by ValueT<int32_t>) {
case ValueT::Null => block {
ClassDestruct(ref(v1),class(ValueT::Null),List((var i32_69:69 = NoneKind(0))))
ClassDestruct(ref(v1),class(ValueT::Null),List((var i32_71:71 = NoneKind(0))))
1
}
} else Unreachable, err: "missing case EnumField(class(ValueT::Elem)) when matching ref(v1) on class(ValueT<ref(i32)>)"
} else BottomKind(0), err: "missing case EnumField(class(ValueT::Elem)) when matching ref(v1) on class(ValueT<ref(i32)>)"
[v2 match {
case ValueT(i32).Null => 1
}] => typeMatch (val v2@57: ValueT<int32_t> = val v1@54: ValueT::Null = instance ValueT::Null() by ValueT<int32_t>) {
}] => typeMatch (val v2@59: ValueT<int32_t> = val v1@56: ValueT::Null = instance ValueT::Null() by ValueT<int32_t>) {
case ValueT::Null => block {
ClassDestruct(ref(v2),class(ValueT::Null),List((var i32_73:73 = NoneKind(0))))
ClassDestruct(ref(v2),class(ValueT::Null),List((var i32_75:75 = NoneKind(0))))
1
}
} else Unreachable, err: "missing case EnumField(class(ValueT::Elem)) when matching ref(v2) on class(ValueT<ref(i32)>)"
} else BottomKind(0), err: "missing case EnumField(class(ValueT::Elem)) when matching ref(v2) on class(ValueT<ref(i32)>)"
32 changes: 16 additions & 16 deletions packages/cosmo/snapshots/Types/fixtures/Type/matches/nat.cos-ast
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,43 @@
case Nat.Zero => 1
}] => typeMatch (instance Nat::Zero() by Nat) {
case Nat::Zero => 1
} else Unreachable, err: "missing case EnumField(class(Nat::Succ)) when matching ins (class(Nat::Zero))() on class(Nat)"
} else BottomKind(0), err: "missing case EnumField(class(Nat::Succ)) when matching ins (class(Nat::Zero))() on class(Nat)"
[Nat.Succ(Nat.Zero) match {
case Nat.Succ(Nat.Zero) => 1
}] => typeMatch (instance Nat::Succ(instance Nat::Zero()) by Nat) {
case Nat::Succ => block {
ClassDestruct(ins (class(Nat::Succ))(ins (class(Nat::Zero))()),class(Nat::Succ),List((var _0_64:64 = NoneKind(0))))
typeMatch (var _0_64@64: Nat = _ by Nat) {
ClassDestruct(ins (class(Nat::Succ))(ins (class(Nat::Zero))()),class(Nat::Succ),List((var _0_66:66 = NoneKind(0))))
typeMatch (var _0_66@66: Nat = _ by Nat) {
case Nat::Zero => 1
} else Unreachable
} else BottomKind(0)
}
} else Unreachable, err: "missing case EnumField(class(Nat::Succ)) when matching (var _0_64:64 = NoneKind(0)) on class(Nat)\nmissing case EnumField(class(Nat::Zero)) when matching ins (class(Nat::Succ))(ins (class(Nat::Zero))()) on class(Nat)"
} else BottomKind(0), err: "missing case EnumField(class(Nat::Succ)) when matching (var _0_66:66 = NoneKind(0)) on class(Nat)\nmissing case EnumField(class(Nat::Zero)) when matching ins (class(Nat::Succ))(ins (class(Nat::Zero))()) on class(Nat)"
[v2 match {
case Nat.Zero => 0
case Nat.Succ(x) => 1
}] => typeMatch (val v2@54: Nat = instance Nat::Succ(instance Nat::Zero()) by Nat) {
}] => typeMatch (val v2@56: Nat = instance Nat::Succ(instance Nat::Zero()) by Nat) {
case Nat::Zero => 0
case Nat::Succ => block {
ClassDestruct(ref(v2),class(Nat::Succ),List((var _0_69:69 = NoneKind(0))))
var x@68: Nat = var _0_69@69: Nat = _
ClassDestruct(ref(v2),class(Nat::Succ),List((var _0_71:71 = NoneKind(0))))
var x@70: Nat = var _0_71@71: Nat = _
1
}
} else Unreachable, err: ""
} else BottomKind(0), err: ""
[v2 match {
case Nat.Zero => 0
case Nat.Succ(Nat.Zero) => 1
case Nat.Succ(Nat.Succ(x)) => 2
}] => typeMatch (val v2@54: Nat = instance Nat::Succ(instance Nat::Zero()) by Nat) {
}] => typeMatch (val v2@56: Nat = instance Nat::Succ(instance Nat::Zero()) by Nat) {
case Nat::Zero => 0
case Nat::Succ => block {
ClassDestruct(ref(v2),class(Nat::Succ),List((var _0_77:77 = NoneKind(0))))
typeMatch (var _0_77@77: Nat = _ by Nat) {
ClassDestruct(ref(v2),class(Nat::Succ),List((var _0_79:79 = NoneKind(0))))
typeMatch (var _0_79@79: Nat = _ by Nat) {
case Nat::Zero => 1
case Nat::Succ => block {
ClassDestruct((var _0_77:77 = NoneKind(0)),class(Nat::Succ),List((var _0_78:78 = NoneKind(0))))
var x@76: Nat = var _0_78@78: Nat = _
ClassDestruct((var _0_79:79 = NoneKind(0)),class(Nat::Succ),List((var _0_80:80 = NoneKind(0))))
var x@78: Nat = var _0_80@80: Nat = _
2
}
} else Unreachable
} else BottomKind(0)
}
} else Unreachable, err: ""
} else BottomKind(0), err: ""
Loading

0 comments on commit 5b409ea

Please sign in to comment.