Skip to content

Commit 321aaf5

Browse files
committed
pkg: Update with new main() requirements across dogfooding and exmaples
1 parent e7ef431 commit 321aaf5

File tree

6 files changed

+115
-35
lines changed

6 files changed

+115
-35
lines changed

build_tools/sharpy_dogfood/prompts.py

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,21 @@ def get_code_generation_prompt(
203203

204204
return f"""You are generating Sharpy code for compiler testing (dogfooding).
205205
206+
## CRITICAL: Program Entry Point Requirement
207+
208+
Every executable Sharpy program MUST have a `main()` function as its entry point:
209+
- All executable statements (print, variable assignments, function calls) must be inside `main()`
210+
- Only declarations (classes, functions, type aliases, static fields with type annotations) can be at module level
211+
- Module-level variables require explicit type annotations: `counter: int = 0`
212+
206213
## CRITICAL: Allowed Features (Phases 0.1.0-0.1.10 ONLY)
207214
208215
### ✅ ALLOWED - Use these features:
209216
217+
#### Program Structure
218+
- **Entry point**: `def main():` is REQUIRED for all executable code
219+
- **Module-level declarations**: classes, functions, constants, static fields (with type annotation)
220+
210221
#### Variables & Types (0.1.3)
211222
- **Variables**: `x: int = 42` or `x = 42` (type inference)
212223
- **Types**: `int`, `str`, `bool`, `float` (primitive types)
@@ -326,9 +337,10 @@ def increment(self) -> None:
326337
def get(self) -> int:
327338
return self.value
328339
329-
c = Counter(10)
330-
c.increment()
331-
print(c.get())
340+
def main():
341+
c = Counter(10)
342+
c.increment()
343+
print(c.get())
332344
333345
# EXPECTED OUTPUT:
334346
# 11
@@ -393,6 +405,13 @@ def get_multifile_generation_prompt(
393405

394406
return f"""You are generating a MULTI-FILE Sharpy project for compiler testing (dogfooding).
395407
408+
## CRITICAL: Program Entry Point Requirement
409+
410+
The `main.spy` file MUST have a `main()` function as its entry point:
411+
- All executable statements (print, variable assignments, function calls) must be inside `main()`
412+
- Library modules (non-main.spy files) do NOT need a `main()` function
413+
- Only declarations (classes, functions, type aliases, static fields) can be at module level
414+
396415
## CRITICAL: Module System Rules (Phase 0.1.10)
397416
398417
### Import Syntax
@@ -406,6 +425,7 @@ def get_multifile_generation_prompt(
406425
- Module name = filename without `.spy` extension
407426
- No `__init__.py` needed (not Python!)
408427
- Modules in same directory can import each other
428+
- The entry point file (`main.spy`) MUST have a `main()` function
409429
410430
### Allowed Features (same as single-file, phases 0.1.0-0.1.10)
411431
- Variables, functions, classes, structs, enums, interfaces
@@ -451,11 +471,12 @@ def __init__(self, v: int):
451471
# Main entry point - imports from module_name
452472
from module_name import helper_function, UtilityClass
453473
454-
result: int = helper_function(5)
455-
print(result)
474+
def main():
475+
result: int = helper_function(5)
476+
print(result)
456477
457-
obj = UtilityClass(10)
458-
print(obj.value)
478+
obj = UtilityClass(10)
479+
print(obj.value)
459480
460481
# EXPECTED OUTPUT:
461482
# 10
@@ -533,9 +554,16 @@ def get_regeneration_prompt(
533554
3. REMOVE or REPLACE the forbidden features
534555
4. Keep the same general logic/intent but use only allowed features
535556
557+
## CRITICAL: Program Entry Point Requirement
558+
559+
Every executable Sharpy program MUST have a `main()` function:
560+
- All executable statements (print, assignments, function calls) must be inside `main()`
561+
- Only declarations (classes, functions, constants) can be at module level
562+
536563
## CRITICAL: Allowed Features (Phases 0.1.0-0.1.10 ONLY)
537564
538565
### ✅ ALLOWED:
566+
- Entry point: `def main():` is REQUIRED for executable code
539567
- Variables: `x: int = 42`
540568
- Types: `int`, `str`, `bool`, `float`, nullable `int?`
541569
- Operators: `+`, `-`, `*`, `/`, `//`, `%`, `**`, `==`, `!=`, `<`, `<=`, `>`, `>=`, `and`, `or`, `not`
@@ -553,6 +581,7 @@ def get_regeneration_prompt(
553581
- Built-ins: `print(value)` - SINGLE ARGUMENT ONLY, `range()` in for loops
554582
555583
### ❌ FORBIDDEN (DO NOT USE):
584+
- NO bare executable statements at module level - wrap in `def main():`
556585
- NO f-strings: `f"hello {{x}}"`
557586
- NO multi-argument print: `print(a, b)` - use multiple print() calls instead
558587
- NO string concatenation: `"a" + "b"`
@@ -595,8 +624,20 @@ def get_spec_validation_prompt(code: str, spec_context: str) -> str:
595624

596625
return f"""You are a STRICT Sharpy language specification validator for phases 0.1.0-0.1.10.
597626
627+
## Program Entry Point Requirement
628+
629+
Every executable Sharpy program MUST have a `main()` function:
630+
- All executable statements (print, assignments without type annotation, function calls) must be inside `main()`
631+
- Only declarations are allowed at module level: classes, functions, constants, static fields (with type annotation)
632+
- Example of valid module-level: `counter: int = 0` (static field with type annotation)
633+
- Example of INVALID module-level: `x = 5` (no type annotation, or bare statement)
634+
598635
## ALLOWED Features (Phases 0.1.0-0.1.10):
599636
637+
### Program Structure
638+
- Entry point: `def main():` is REQUIRED for executable code
639+
- Module-level declarations: classes, functions, constants, static fields (with type annotation)
640+
600641
### Variables & Types (0.1.3)
601642
- Variable declaration: `x: int = 42` or `x = 42` (inference)
602643
- Primitive types: `int`, `str`, `bool`, `float`
@@ -674,6 +715,7 @@ def get_spec_validation_prompt(code: str, spec_context: str) -> str:
674715
675716
## FORBIDDEN Features (NOT in phases 0.1.0-0.1.10):
676717
718+
❌ Bare executable statements at module level (must be in `main()`) - REJECT
677719
❌ f-strings: `f"text {{var}}"` - REJECT
678720
❌ Multi-argument print: `print(a, b, c)` - REJECT (use multiple print calls)
679721
❌ Lists/dicts/sets literals: `[]`, `{{}}`, `set()` - REJECT (v0.1.11)
Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Variable Declaration and Assignment
22

3-
Variables in Sharpy must be declared and assigned in a single statement. There are three syntactic forms:
3+
Variables in Sharpy must be declared and assigned in a single statement. Variable declarations with type inference (Forms 2 and 3 below) are only allowed inside functions; module-level declarations require explicit type annotations.
4+
5+
There are three syntactic forms:
46

57
| Form | Syntax | Type Determination |
68
|------|--------|-------------------|
@@ -10,63 +12,80 @@ Variables in Sharpy must be declared and assigned in a single statement. There a
1012

1113
**Form 1: Explicit Type Annotation**
1214

13-
The type is explicitly specified:
15+
The type is explicitly specified. This form can be used both at module level (static fields) and inside functions:
1416

1517
```python
16-
count: int = 0
17-
name: str = "Alice"
18-
items: list[int] = [1, 2, 3]
19-
user: User? = None
18+
# Module level (static fields) - explicit type REQUIRED
19+
counter: int = 0
20+
config: str = "default"
21+
22+
def main():
23+
# Inside functions - explicit type allowed
24+
count: int = 0
25+
name: str = "Alice"
26+
items: list[int] = [1, 2, 3]
27+
user: User? = None
2028
```
2129

2230
**Form 2: Type Inference (Implicit)**
2331

24-
The type is inferred from the initializer expression:
32+
The type is inferred from the initializer expression. This form is **only allowed inside functions**, not at module level:
2533

2634
```python
27-
count = 0 # Inferred as int
28-
name = "Alice" # Inferred as str
29-
items = [1, 2, 3] # Inferred as list[int]
30-
pi = 3.14159 # Inferred as float
35+
def main():
36+
count = 0 # Inferred as int
37+
name = "Alice" # Inferred as str
38+
items = [1, 2, 3] # Inferred as list[int]
39+
pi = 3.14159 # Inferred as float
40+
41+
# ❌ NOT allowed at module level:
42+
# count = 0 # ERROR: module-level requires type annotation
3143
```
3244

3345
**Form 3: Type Inference (Explicit with `auto`)**
3446

35-
The `auto` keyword explicitly requests type inference. This is functionally equivalent to Form 2 but makes the inference explicit:
47+
The `auto` keyword explicitly requests type inference. This is functionally equivalent to Form 2 but makes the inference explicit. Like Form 2, this is **only allowed inside functions**:
3648

3749
```python
38-
count: auto = 0 # Inferred as int
39-
name: auto = "Alice" # Inferred as str
40-
items: auto = [1, 2, 3] # Inferred as list[int]
50+
def main():
51+
count: auto = 0 # Inferred as int
52+
name: auto = "Alice" # Inferred as str
53+
items: auto = [1, 2, 3] # Inferred as list[int]
4154
```
4255

4356
**When to Use `auto`:**
4457

4558
The `auto` keyword is primarily useful for variable shadowing, where you want to redeclare a variable with a different type:
4659

4760
```python
48-
x: int = 5
49-
x = 10 # Assignment to existing int variable
50-
x: str = "hello" # Shadowing: new variable of type str
51-
x: auto = [1, 2, 3] # Shadowing: new variable, type inferred as list[int]
61+
def main():
62+
x: int = 5
63+
x = 10 # Assignment to existing int variable
64+
x: str = "hello" # Shadowing: new variable of type str
65+
x: auto = [1, 2, 3] # Shadowing: new variable, type inferred as list[int]
5266
```
5367

5468
## No Declaration Without Assignment
5569

5670
Unlike some languages, Sharpy does not allow variable declarations without initialization:
5771

5872
```python
59-
# ❌ Invalid - no declaration without assignment
60-
x: int # ERROR: variable declaration requires initializer
61-
name: str # ERROR: variable declaration requires initializer
62-
63-
# ✅ Valid - always provide initializer
64-
x: int = 0
65-
name: str = ""
66-
items: list[int] = []
67-
user: User? = None
73+
def main():
74+
# ❌ Invalid - no declaration without assignment
75+
x: int # ERROR: variable declaration requires initializer
76+
name: str # ERROR: variable declaration requires initializer
77+
78+
# ✅ Valid - always provide initializer
79+
x: int = 0
80+
name: str = ""
81+
items: list[int] = []
82+
user: User? = None
6883
```
6984

7085
**Exception: Class Instance Fields**
7186

7287
Class and struct fields can be declared without initialization if they are assigned in `__init__`.
88+
89+
## Module-Level vs Function-Level Variables
90+
91+
See [Program Entry Point](program_entry_point.md) for details on module-level declarations vs executable statements inside `main()`.

snippets/class.spy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Parser test file - contains syntax not yet fully supported
2+
# This file is for AST/parser testing, not execution
3+
14
class Foo:
25
x: int
36
y: str

snippets/example.spy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Parser test file - contains syntax not yet fully supported (try/except, string concat, etc.)
2+
# This file is for AST/parser testing, not execution
3+
14
class Example:
25
x: int = 42
36
blah: list[list[float]] = []

snippets/functions.spy

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Function definitions (library module - no main() needed if imported)
2+
# To run standalone, uncomment the main() function below
3+
14
def foobar():
25
pass
36

@@ -13,3 +16,10 @@ def fibonacci(n: int) -> int:
1316
return 1
1417
else:
1518
return fibonacci(n - 1) + fibonacci(n - 2)
19+
20+
21+
def main():
22+
# Example usage
23+
foobar()
24+
print(add(3, 5))
25+
print(fibonacci(10))

snippets/objects.spy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Parser test file - contains syntax not yet fully supported (f-strings)
2+
# This file is for AST/parser testing, not execution
3+
14
class Foo:
25
_value: int
36

0 commit comments

Comments
 (0)