Skip to content

Commit 2c06529

Browse files
committed
fix: Returning type is now required
1 parent bd56252 commit 2c06529

File tree

13 files changed

+173
-60
lines changed

13 files changed

+173
-60
lines changed

.makim.yaml

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,20 @@ groups:
8585
type: string
8686
required: true
8787
run: |
88+
import subprocess
89+
8890
for name in "${{ args.examples }}".split(","):
8991
print(f" show tokens: {name} ".center(80, "="))
90-
arx --show-tokens examples/@(name).x
92+
result = subprocess.run(
93+
["arx", "--show-tokens", f"examples/{name}.x"],
94+
capture_output=True,
95+
text=True,
96+
check=True,
97+
)
98+
output = result.stdout.strip()
99+
if not output:
100+
raise RuntimeError(f"show-tokens produced no output for: {name}")
101+
print(output)
91102
show-ast:
92103
help: Emit ast for input file
93104
args:
@@ -96,9 +107,25 @@ groups:
96107
type: string
97108
required: true
98109
run: |
110+
import subprocess
111+
99112
for name in "${{ args.examples }}".split(","):
100113
print(f" show ast: {name} ".center(80, "="))
101-
arx --show-ast examples/@(name).x
114+
result = subprocess.run(
115+
["arx", "--show-ast", f"examples/{name}.x"],
116+
capture_output=True,
117+
text=True,
118+
check=True,
119+
)
120+
output = result.stdout.strip()
121+
if not output:
122+
raise RuntimeError(f"show-ast produced no output for: {name}")
123+
if output == "Block":
124+
raise RuntimeError(
125+
"show-ast regression: got only 'Block'. "
126+
f"example={name}"
127+
)
128+
print(output)
102129
show-llvm-ir:
103130
help: Emit ast for input file
104131
args:
@@ -107,9 +134,23 @@ groups:
107134
type: string
108135
required: true
109136
run: |
137+
import subprocess
138+
110139
for name in "${{ args.examples }}".split(","):
111140
print(f" show llvm ir: {name} ".center(80, "="))
112-
arx --show-llvm-ir examples/@(name).x
141+
result = subprocess.run(
142+
["arx", "--show-llvm-ir", f"examples/{name}.x"],
143+
capture_output=True,
144+
text=True,
145+
check=True,
146+
)
147+
output = result.stdout.strip()
148+
if "; ModuleID" not in output:
149+
raise RuntimeError(
150+
"show-llvm-ir output missing LLVM header for: "
151+
f"{name}"
152+
)
153+
print(output)
113154
emit-object:
114155
help: Emit ast for input file
115156
args:
@@ -118,9 +159,34 @@ groups:
118159
type: string
119160
required: true
120161
run: |
162+
import subprocess
163+
164+
from pathlib import Path
165+
166+
output_dir = Path("build/smoke")
167+
output_dir.mkdir(parents=True, exist_ok=True)
168+
121169
for name in "${{ args.examples }}".split(","):
122170
print(f" emit object: {name} ".center(80, "="))
123-
arx examples/@(name).x
171+
output_file = output_dir / name
172+
if output_file.exists():
173+
output_file.unlink()
174+
subprocess.run(
175+
[
176+
"arx",
177+
f"examples/{name}.x",
178+
"--lib",
179+
"--output-file",
180+
str(output_file),
181+
],
182+
check=True,
183+
)
184+
if not output_file.exists() or output_file.stat().st_size == 0:
185+
raise RuntimeError(
186+
"emit-object did not produce a valid artifact for: "
187+
f"{name}"
188+
)
189+
print(str(output_file))
124190
125191
docs:
126192
tasks:

AGENTS.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,11 @@ Current language behavior (from parser/lexer/tests/syntax manifest):
9494
- Numeric literals: decimal integer/float (single `.` max)
9595
- String/char/bool/none literals are supported
9696
- Comments: `#` line comments
97-
- Function definitions: `fn name(arg: type, ...)` followed by indented block
97+
- Function definitions: `fn name(arg: type, ...) -> type` followed by indented
98+
block
9899
- Function arguments must be explicitly typed
99-
- Extern definitions: `extern name(arg: type, ...)`
100+
- Variable declarations must be explicitly typed (`var name: type`)
101+
- Extern definitions: `extern name(arg: type, ...) -> type`
100102
- Control flow: `if/else`, `while`, `for ... in (...)`, count-style `for`
101103
- Range-style for header is `(start:end:step)` (tuple-style is rejected)
102104
- Builtins: `cast(value, type)` and `print(expr)`

docs/getting-started.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,13 @@ Variables are declared with `var`:
273273
title: Variable example
274274
summary: Shows var binding inside a function.
275275
```
276-
fn example():
276+
fn example() -> i32:
277277
```
278278
title: example
279279
summary: Binds a variable and computes a result.
280280
```
281-
var a = 10 in
282-
a + 1
281+
var a: i32 = 10
282+
return a + 1
283283
````
284284

285285
### Extern Functions

docs/library/datatypes.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# Data Types
22

33
Arx uses explicit type annotations for variables, function parameters, and
4-
optional function return types.
4+
function return types.
55

66
## Type Annotations
77

88
- Function parameters must always be typed.
9-
- Function return type is optional. If omitted, current parser default is `f32`.
10-
- Variable declarations can include an explicit type with `var name: type`.
9+
- Function return type must always be explicit with `-> type`.
10+
- Variable declarations must include an explicit type with `var name: type`.
1111

1212
````arx
1313
```

docs/library/docstrings.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Valid:
4545
```
4646
title: Module docs
4747
```
48-
fn main():
48+
fn main() -> i32:
4949
```
5050
title: main
5151
summary: Entry point for the module.
@@ -61,7 +61,7 @@ after `:` and the required newline/indentation.
6161
Valid:
6262

6363
````text
64-
fn main():
64+
fn main() -> i32:
6565
```
6666
title: Function docs
6767
summary: Function summary
@@ -72,7 +72,7 @@ fn main():
7272
Invalid:
7373

7474
````text
75-
fn main():
75+
fn main() -> i32:
7676
return 1
7777
```
7878
title: Too late

docs/library/functions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ fn double(v: i32) -> i32:
3232
```
3333
return v * 2
3434
35-
fn main():
35+
fn main() -> i32:
3636
```
3737
title: main
3838
summary: Calls double with a constant input.

docs/library/modules.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Valid:
4141
```
4242
title: Module docs
4343
```
44-
fn main():
44+
fn main() -> i32:
4545
```
4646
title: main
4747
summary: Entry point for the module.
@@ -55,7 +55,7 @@ Invalid (leading indentation before module docstring):
5555
```
5656
title: Module docs
5757
```
58-
fn main():
58+
fn main() -> i32:
5959
```
6060
title: main
6161
summary: Entry point for the module.

src/arx/parser.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -596,10 +596,14 @@ def parse_inline_var_declaration(self) -> astx.InlineVariableDeclaration:
596596
name = cast(str, self.tokens.cur_tok.value)
597597
self.tokens.get_next_token() # eat identifier
598598

599-
var_type: astx.DataType = astx.Float32()
600-
if self._is_operator(":"):
601-
self._consume_operator(":")
602-
var_type = self.parse_type()
599+
if not self._is_operator(":"):
600+
raise ParserException(
601+
"Parser: Expected type annotation for inline variable "
602+
f"'{name}'."
603+
)
604+
605+
self._consume_operator(":")
606+
var_type = self.parse_type()
603607

604608
self._consume_operator("=")
605609
value = self.parse_expression()
@@ -626,10 +630,13 @@ def parse_var_expr(self) -> astx.VariableDeclaration:
626630
name = cast(str, self.tokens.cur_tok.value)
627631
self.tokens.get_next_token() # eat identifier
628632

629-
var_type: astx.DataType = astx.Float32()
630-
if self._is_operator(":"):
631-
self._consume_operator(":")
632-
var_type = self.parse_type()
633+
if not self._is_operator(":"):
634+
raise ParserException(
635+
f"Parser: Expected type annotation for variable '{name}'."
636+
)
637+
638+
self._consume_operator(":")
639+
var_type = self.parse_type()
633640

634641
value: astx.Expr | None = None
635642
if self._is_operator("="):
@@ -824,10 +831,13 @@ def parse_prototype(self, expect_colon: bool) -> astx.FunctionPrototype:
824831

825832
self._consume_operator(")")
826833

827-
ret_type: astx.DataType = astx.Float32()
828-
if self._is_operator("->"):
829-
self._consume_operator("->")
830-
ret_type = self.parse_type()
834+
if not self._is_operator("->"):
835+
raise ParserException(
836+
"Parser: Expected return type annotation with '->'."
837+
)
838+
839+
self._consume_operator("->")
840+
ret_type = self.parse_type()
831841

832842
if expect_colon:
833843
self._consume_operator(":")

tests/test_app_paths.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def test_arxio_file_and_stdin_loaders(
105105
type: Path
106106
"""
107107
sample = tmp_path / "sample.x"
108-
sample.write_text("fn main():\n return 1\n", encoding="utf-8")
108+
sample.write_text("fn main() -> i32:\n return 1\n", encoding="utf-8")
109109
ArxIO.file_to_buffer(str(sample))
110110
assert "fn main()" in ArxIO.buffer.buffer
111111

tests/test_codegen_ast_output.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
@pytest.mark.parametrize(
1414
"code",
1515
[
16-
"fn main():\n return 0.0 + 1.0",
17-
"fn main():\n return 1.0 + 2.0 * (3.0 - 2.0)",
16+
"fn main() -> f32:\n return 0.0 + 1.0",
17+
"fn main() -> f32:\n return 1.0 + 2.0 * (3.0 - 2.0)",
1818
"fn main() -> i32:\n print(42)\n return 0",
1919
"fn main() -> i32:\n print(3.5)\n return 0",
2020
(

0 commit comments

Comments
 (0)