Skip to content

Commit e73c7c9

Browse files
committed
- Fix pipe expressions producing malformed TypeScript output
- Fix optional parentheses incorrectly transforming comments - Fix complex pipe chains with method calls not working - Update examples to only include implemented features - Add comprehensive test coverage for edge cases
1 parent af257b8 commit e73c7c9

File tree

22 files changed

+962
-905
lines changed

22 files changed

+962
-905
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.1.4
1+
0.1.5

bunfig.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,9 @@ preload = ["./src/preload.ts"]
66
# Optional: Add file extensions
77
[build]
88
# Recognize .zs files
9-
extensions = [".zs", ".ts", ".tsx", ".js", ".jsx"]
9+
extensions = [".zs", ".ts", ".tsx", ".js", ".jsx"]
10+
11+
# Test configuration
12+
[test]
13+
# Include .zs files in test pattern matching
14+
preload = ["./src/preload.ts"]

examples/advanced.zs

Lines changed: 76 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,24 @@
22

33
// Generic container types
44
struct Option<T> {
5-
value: T?;
5+
value: T;
66
isSome: boolean;
77
}
88

99
struct Result<T, E> {
10-
value: T?;
11-
error: E?;
10+
value: T;
11+
error: E;
1212
isOk: boolean;
1313
}
1414

15-
// Advanced traits
15+
// Advanced traits
1616
trait Functor<T> {
17-
map<U>(fn: (value: T) => U): Functor<U>;
18-
}
19-
20-
trait Monad<T> extends Functor<T> {
21-
flatMap<U>(fn: (value: T) => Monad<U>): Monad<U>;
22-
unit<U>(value: U): Monad<U>;
23-
}
24-
25-
// Complex implementations
26-
impl Functor<T> for Option<T> {
27-
map<U>(fn: (value: T) => U) {
28-
return match this.isSome {
29-
true => Option.some(fn(this.value))
30-
false => Option.none()
31-
};
32-
}
33-
}
34-
35-
impl Monad<T> for Option<T> {
36-
flatMap<U>(fn: (value: T) => Option<U>) {
37-
return match this.isSome {
38-
true => fn(this.value)
39-
false => Option.none()
40-
};
41-
}
42-
43-
unit<U>(value: U) {
44-
return Option.some(value);
45-
}
17+
map(fn: any): any;
4618
}
4719

48-
impl Option<T> {
49-
some(value: T) {
50-
return { value, isSome: true };
51-
}
52-
53-
none() {
54-
return { value: null, isSome: false };
55-
}
56-
57-
unwrap() {
58-
return match this.isSome {
59-
true => this.value
60-
false => panic("Called unwrap on None value")
61-
};
62-
}
63-
64-
unwrapOr(defaultValue: T) {
65-
return match this.isSome {
66-
true => this.value
67-
false => defaultValue
68-
};
69-
}
20+
trait Monad<T> {
21+
flatMap(fn: any): any;
22+
unit(value: any): any;
7023
}
7124

7225
// State management with atoms
@@ -80,7 +33,7 @@ let stateTransition = match appState {
8033
_ => :error
8134
}
8235

83-
// Complex data processing pipeline
36+
// Complex data processing
8437
struct User {
8538
id: number;
8639
name: string;
@@ -93,67 +46,81 @@ struct ValidationError {
9346
message: string;
9447
}
9548

96-
// Validation functions (would be implemented in TypeScript)
97-
let validateUser = (user: User) => {
98-
let errors = []
99-
100-
let nameValidation = match user.name.length {
101-
0 => Option.some({ field: "name", message: "Name is required" })
102-
len when len < 2 => Option.some({ field: "name", message: "Name too short" })
103-
_ => Option.none()
104-
}
105-
106-
let emailValidation = match user.email.includes("@") {
107-
false => Option.some({ field: "email", message: "Invalid email format" })
108-
true => Option.none()
109-
}
110-
111-
return match [nameValidation, emailValidation] {
112-
[none, none] => Result.ok(user)
113-
errors => Result.error(errors.filter(e => e.isSome).map(e => e.unwrap()))
49+
// Create sample users
50+
let user1 = { id: 1, name: "Alice", email: "[email protected]", isActive: true }
51+
let user2 = { id: 2, name: "Bob", email: "[email protected]", isActive: false }
52+
let user3 = { id: 3, name: "", email: "invalid", isActive: true }
53+
54+
// Pattern matching for validation
55+
let validateName = (name) => {
56+
return match name.length {
57+
0 => :invalid_empty
58+
1 => :invalid_short
59+
_ => :valid
11460
}
11561
}
11662

117-
// Functional composition
118-
let processUsers = (users: User[]) => {
119-
return users
120-
|> filter(user => user.isActive)
121-
|> map(validateUser)
122-
|> filter(result => result.isOk)
123-
|> map(result => result.unwrap())
63+
let validateEmail = (email) => {
64+
return match email.includes("@") {
65+
true => :valid
66+
false => :invalid_format
67+
}
12468
}
12569

126-
// Pattern matching with complex conditions
127-
let categorizeUser = (user: User) => {
128-
return match [user.isActive, user.email.endsWith(".com")] {
129-
[true, true] => :premium
130-
[true, false] => :standard
131-
[false, _] => :inactive
70+
// User categorization
71+
let categorizeUser = (user) => {
72+
let nameStatus = validateName user.name
73+
let emailStatus = validateEmail user.email
74+
75+
return match nameStatus {
76+
:valid => match emailStatus {
77+
:valid => :premium_user
78+
_ => :standard_user
79+
}
80+
_ => :invalid_user
13281
}
13382
}
13483

135-
// Higher-order functions simulation
136-
struct Pipeline<T> {
137-
value: T;
138-
}
84+
// Process multiple users
85+
let user1Category = categorizeUser user1
86+
let user2Category = categorizeUser user2
87+
let user3Category = categorizeUser user3
13988

140-
impl Pipeline<T> {
141-
new(value: T) {
142-
return { value };
143-
}
144-
145-
then<U>(fn: (value: T) => U) {
146-
return Pipeline.new(fn(this.value));
147-
}
148-
149-
execute() {
150-
return this.value;
151-
}
89+
// Output results
90+
console.log "User categories:"
91+
console.log user1Category
92+
console.log user2Category
93+
console.log user3Category
94+
95+
// Chained data transformations
96+
let data = "zenoscript programming"
97+
let processed = data |> toUpperCase |> trim |> console.log
98+
99+
// State transitions
100+
let currentState = :idle
101+
let nextState = match currentState {
102+
:idle => :loading
103+
:loading => :processing
104+
:processing => :complete
105+
:complete => :idle
106+
_ => :error
152107
}
153108

154-
// Usage example
155-
let result = Pipeline.new(42)
156-
|> then(x => x * 2)
157-
|> then(x => x + 10)
158-
|> then(x => x.toString())
159-
|> execute
109+
console.log "State transition:"
110+
console.log nextState
111+
112+
// Complex matching with multiple atoms
113+
let systemStatus = :healthy
114+
let userLoad = :medium
115+
116+
let recommendation = match systemStatus {
117+
:healthy => match userLoad {
118+
:low => :scale_down
119+
:medium => :maintain
120+
:high => :scale_up
121+
_ => :monitor
122+
}
123+
:degraded => :investigate
124+
:critical => :emergency_scale
125+
_ => :unknown_action
126+
}

examples/basic.zs

Lines changed: 27 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,47 +13,23 @@ struct ApiResponse<T> {
1313
message: string;
1414
}
1515

16-
// Trait declaration
16+
// Trait declarations
1717
trait Serializable {
1818
serialize(): string;
19-
deserialize(data: string): Self;
19+
deserialize(data: string): any;
2020
}
2121

2222
trait Displayable {
2323
display(): string;
2424
}
2525

26-
// Implementation blocks
27-
impl User {
28-
new(name: string, email: string, age: number) {
29-
return { name, email, age };
30-
}
31-
32-
isAdult() {
33-
return this.age >= 18;
34-
}
35-
}
36-
37-
impl Serializable for User {
38-
serialize() {
39-
return JSON.stringify(this);
40-
}
41-
42-
deserialize(data: string) {
43-
return JSON.parse(data);
44-
}
45-
}
46-
47-
impl Displayable for User {
48-
display() {
49-
return `${this.name} (${this.email})`;
50-
}
51-
}
26+
// Let bindings and values
27+
let userName = "Alice"
28+
let userEmail = "[email protected]"
29+
let userAge = 25
5230

53-
// Let bindings and pipe expressions
54-
let user = User.new("Alice", "[email protected]", 25)
55-
let userJson = user |> serialize
56-
let displayStr = user |> display
31+
// Create user object
32+
let user = { name: userName, email: userEmail, age: userAge }
5733

5834
// Atoms and pattern matching
5935
let status = :loading
@@ -66,25 +42,30 @@ let statusMessage = match status {
6642
_ => "Unknown status"
6743
}
6844

69-
// More complex pattern matching with guards
70-
let userStatus = match user.age {
71-
age when age < 13 => :child
72-
age when age < 18 => :teenager
73-
age when age < 65 => :adult
74-
_ => :senior
75-
}
45+
// Simple pipe operations
46+
let greeting = " Hello World " |> trim |> toUpperCase
47+
let result = greeting |> console.log
7648

77-
// Chained pipe operations
78-
let processedData = " Hello World "
79-
|> trim
80-
|> toUpperCase
81-
|> console.log
49+
// More pipe examples
50+
let data = "zenoscript"
51+
let processed = data |> toUpperCase |> console.log
8252

83-
// Generic usage
53+
// Object creation and JSON
8454
let apiResponse = {
8555
status: 200,
8656
data: user,
8757
message: "User retrieved successfully"
8858
}
8959

90-
let response = apiResponse |> serialize
60+
// Function calls with optional parentheses
61+
console.log "Status message:"
62+
console.log statusMessage
63+
64+
// Conditional logic with simplified if
65+
if userAge >= 18 {
66+
console.log "User is an adult"
67+
}
68+
69+
if status == :loading {
70+
console.log "Currently loading..."
71+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "zenoscript",
3-
"version": "0.1.4",
3+
"version": "0.1.5",
44
"description": "A functional programming language that compiles to TypeScript",
55
"main": "src/index.ts",
66
"module": "src/index.ts",

0 commit comments

Comments
 (0)