Skip to content

Commit d9fbd9d

Browse files
committed
Allow omitting parentheses in function type when it has one parameter
1 parent 6795404 commit d9fbd9d

File tree

6 files changed

+185
-14
lines changed
  • src
    • antlr-smooth/src/main/antlr/org/smoothbuild/antlr/lang
    • compiler-frontend/src
      • main/java/org/smoothbuild/compilerfrontend/compile/task
      • test/java/org/smoothbuild/compilerfrontend/acceptance

6 files changed

+185
-14
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
Change Log
33
==========
44

5+
Version ?????? (??????????)
6+
---------------------------
7+
8+
* extend smooth syntax: Allow omitting parentheses in function type when it has one parameter
9+
510
Version 0.23.0 (2025.03.20)
611
---------------------------
712

src/antlr-smooth/src/main/antlr/org/smoothbuild/antlr/lang/SmoothAntlr.g4

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,13 @@ lambda
8888
;
8989

9090
type
91+
: nonFuncType # notFuncType
92+
| (nonFuncType | '(' (type (',' type)*)? ')') '->' type # funcType
93+
;
94+
95+
nonFuncType
9196
: NAME # typeName
9297
| '[' type ']' # arrayType
93-
| '(' (type (',' type)*)? ')' '->' type # funcType
9498
;
9599

96100
NAME

src/compiler-frontend/src/main/java/org/smoothbuild/compilerfrontend/compile/task/TranslateAp.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.smoothbuild.antlr.lang.SmoothAntlrParser.ItemListContext;
3232
import org.smoothbuild.antlr.lang.SmoothAntlrParser.LambdaContext;
3333
import org.smoothbuild.antlr.lang.SmoothAntlrParser.ModuleContext;
34+
import org.smoothbuild.antlr.lang.SmoothAntlrParser.NonFuncTypeContext;
35+
import org.smoothbuild.antlr.lang.SmoothAntlrParser.NotFuncTypeContext;
3436
import org.smoothbuild.antlr.lang.SmoothAntlrParser.PipeContext;
3537
import org.smoothbuild.antlr.lang.SmoothAntlrParser.SelectContext;
3638
import org.smoothbuild.antlr.lang.SmoothAntlrParser.StructContext;
@@ -362,13 +364,20 @@ private PType createTypeSane(TypeContext type, Location location) {
362364

363365
private PExplicitType createType(TypeContext type) {
364366
return switch (type) {
365-
case TypeNameContext name -> createTypeReference(name);
366-
case ArrayTypeContext arrayType -> createArrayType(arrayType);
367+
case NotFuncTypeContext notFuncType -> createNotFuncType(notFuncType.nonFuncType());
367368
case FuncTypeContext funcType -> createFuncType(funcType);
368369
default -> throw unexpectedCaseException(type);
369370
};
370371
}
371372

373+
private PExplicitType createNotFuncType(NonFuncTypeContext notFuncType) {
374+
return switch (notFuncType) {
375+
case TypeNameContext name -> createTypeReference(name);
376+
case ArrayTypeContext arrayType -> createArrayType(arrayType);
377+
default -> throw unexpectedCaseException(notFuncType);
378+
};
379+
}
380+
372381
private PExplicitType createTypeReference(TypeNameContext type) {
373382
return new PTypeReference(type.getText(), fileLocation(fullPath, type.NAME()));
374383
}
@@ -379,10 +388,16 @@ private PExplicitType createArrayType(ArrayTypeContext arrayType) {
379388
}
380389

381390
private PExplicitType createFuncType(FuncTypeContext funcType) {
382-
var types = listOfAll(funcType.type()).map(this::createType);
383-
var resultType = types.get(types.size() - 1);
384-
var paramTypes = types.subList(0, types.size() - 1);
385-
return new PFuncType(resultType, paramTypes, fileLocation(fullPath, funcType));
391+
if (funcType.nonFuncType() != null) {
392+
var resultType = createType(funcType.type().get(0));
393+
var paramTypes = list(createNotFuncType(funcType.nonFuncType()));
394+
return new PFuncType(resultType, paramTypes, fileLocation(fullPath, funcType));
395+
} else {
396+
var types = listOfAll(funcType.type()).map(this::createType);
397+
var resultType = types.get(types.size() - 1);
398+
var paramTypes = types.subList(0, types.size() - 1);
399+
return new PFuncType(resultType, paramTypes, fileLocation(fullPath, funcType));
400+
}
386401
}
387402

388403
private RuntimeException newRuntimeException(Class<?> clazz) {
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
11
Log{ERROR, '{t-project}/module.smooth:1: mismatched input '[' expecting {'>', NAME}
22
Int result<[7]> = 7;
3-
^'}
4-
Log{ERROR, '{t-project}/module.smooth:1: mismatched input '7' expecting {'(', '[', NAME}
5-
Int result<[7]> = 7;
6-
^'}
7-
Log{ERROR, '{t-project}/module.smooth:1: mismatched input '>' expecting NAME
8-
Int result<[7]> = 7;
9-
^'}
3+
^'}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
SModule(
2+
types = [
3+
]
4+
evaluables = [
5+
funcReturningFuncCase=sPolyEvaluable(
6+
typeParams = []
7+
evaluable = SNamedExprValue(
8+
type = [(String)->(Blob)->Int]
9+
fqn = funcReturningFuncCase
10+
location = {t-project}/module.smooth:1
11+
body = SOrder(
12+
evaluationType = [(String)->(Blob)->Int]
13+
elements = [
14+
]
15+
location = {t-project}/module.smooth:1
16+
)
17+
)
18+
)
19+
funcReturningFuncCaseWithUnnecessaryParentheses=sPolyEvaluable(
20+
typeParams = []
21+
evaluable = SNamedExprValue(
22+
type = [(String)->(Blob)->Int]
23+
fqn = funcReturningFuncCaseWithUnnecessaryParentheses
24+
location = {t-project}/module.smooth:2
25+
body = SOrder(
26+
evaluationType = [(String)->(Blob)->Int]
27+
elements = [
28+
]
29+
location = {t-project}/module.smooth:2
30+
)
31+
)
32+
)
33+
funcTakingFuncTypeParamCase=sPolyEvaluable(
34+
typeParams = []
35+
evaluable = SNamedExprValue(
36+
type = [((String)->Blob)->Int]
37+
fqn = funcTakingFuncTypeParamCase
38+
location = {t-project}/module.smooth:4
39+
body = SOrder(
40+
evaluationType = [((String)->Blob)->Int]
41+
elements = [
42+
]
43+
location = {t-project}/module.smooth:4
44+
)
45+
)
46+
)
47+
funcTakingFuncTypeParamCaseWithUnnecessaryParentheses=sPolyEvaluable(
48+
typeParams = []
49+
evaluable = SNamedExprValue(
50+
type = [((String)->Blob)->Int]
51+
fqn = funcTakingFuncTypeParamCaseWithUnnecessaryParentheses
52+
location = {t-project}/module.smooth:5
53+
body = SOrder(
54+
evaluationType = [((String)->Blob)->Int]
55+
elements = [
56+
]
57+
location = {t-project}/module.smooth:5
58+
)
59+
)
60+
)
61+
]
62+
scope = SScope(
63+
types = [
64+
Blob -> STypeDefinition(
65+
type = Blob
66+
fqn = Blob
67+
location = internal
68+
)
69+
Bool -> STypeDefinition(
70+
type = Bool
71+
fqn = Bool
72+
location = internal
73+
)
74+
Int -> STypeDefinition(
75+
type = Int
76+
fqn = Int
77+
location = internal
78+
)
79+
String -> STypeDefinition(
80+
type = String
81+
fqn = String
82+
location = internal
83+
)
84+
<empty bindings>
85+
<empty bindings>
86+
]
87+
evaluables = [
88+
<empty bindings>
89+
<empty bindings>
90+
funcReturningFuncCase -> sPolyEvaluable(
91+
typeParams = []
92+
evaluable = SNamedExprValue(
93+
type = [(String)->(Blob)->Int]
94+
fqn = funcReturningFuncCase
95+
location = {t-project}/module.smooth:1
96+
body = SOrder(
97+
evaluationType = [(String)->(Blob)->Int]
98+
elements = [
99+
]
100+
location = {t-project}/module.smooth:1
101+
)
102+
)
103+
)
104+
funcReturningFuncCaseWithUnnecessaryParentheses -> sPolyEvaluable(
105+
typeParams = []
106+
evaluable = SNamedExprValue(
107+
type = [(String)->(Blob)->Int]
108+
fqn = funcReturningFuncCaseWithUnnecessaryParentheses
109+
location = {t-project}/module.smooth:2
110+
body = SOrder(
111+
evaluationType = [(String)->(Blob)->Int]
112+
elements = [
113+
]
114+
location = {t-project}/module.smooth:2
115+
)
116+
)
117+
)
118+
funcTakingFuncTypeParamCase -> sPolyEvaluable(
119+
typeParams = []
120+
evaluable = SNamedExprValue(
121+
type = [((String)->Blob)->Int]
122+
fqn = funcTakingFuncTypeParamCase
123+
location = {t-project}/module.smooth:4
124+
body = SOrder(
125+
evaluationType = [((String)->Blob)->Int]
126+
elements = [
127+
]
128+
location = {t-project}/module.smooth:4
129+
)
130+
)
131+
)
132+
funcTakingFuncTypeParamCaseWithUnnecessaryParentheses -> sPolyEvaluable(
133+
typeParams = []
134+
evaluable = SNamedExprValue(
135+
type = [((String)->Blob)->Int]
136+
fqn = funcTakingFuncTypeParamCaseWithUnnecessaryParentheses
137+
location = {t-project}/module.smooth:5
138+
body = SOrder(
139+
evaluationType = [((String)->Blob)->Int]
140+
elements = [
141+
]
142+
location = {t-project}/module.smooth:5
143+
)
144+
)
145+
)
146+
]
147+
)
148+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[String->Blob->Int] funcReturningFuncCase = [];
2+
[(String)->(Blob)->Int] funcReturningFuncCaseWithUnnecessaryParentheses = [];
3+
4+
[(String->Blob)->Int] funcTakingFuncTypeParamCase = [];
5+
[((String)->Blob)->Int] funcTakingFuncTypeParamCaseWithUnnecessaryParentheses = [];

0 commit comments

Comments
 (0)