Skip to content

Commit 27a5805

Browse files
authored
Merge pull request #47 from comroid-git/conditional-class-members
Conditional class members
2 parents 575fdf3 + c8dbdb9 commit 27a5805

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+703
-335
lines changed

Test Execute.run.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<component name="ProjectRunConfigurationManager">
22
<configuration default="false" name="Test Execute" type="DotNetProject" factoryName=".NET Project">
33
<option name="EXE_PATH" value="$PROJECT_DIR$/kscr-build/bin/net6.0/kscr.exe" />
4-
<option name="PROGRAM_PARAMETERS" value="execute --debug --pkgbase org.comroid.kscr.test --source examples/PrintNumbers.kscr --output examples/build/compile/" />
4+
<option name="PROGRAM_PARAMETERS" value="execute --debug --pkgbase org.comroid.kscr.test --source examples/testing/src/main/org/comroid/kscr/test/PrintNumbers.kscr --output examples/build/compile/" />
55
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/" />
66
<option name="PASS_PARENT_ENVS" value="1" />
77
<option name="USE_EXTERNAL_CONSOLE" value="0" />

examples/testing/src/main/org/comroid/kscr/test/PrintNumbers.kscr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import org.comroid.kscr.core.Throwable;
44
import org.comroid.kscr.core.Sequencable;
55
import org.comroid.kscr.time.DateTime;
66

7-
public class PrintNumbers implements Throwable {
7+
public class PrintNumbers : Throwable {
88
public static int StackSize => 64;
99
public int StackValue => 48;
1010
// we can add a setter implementation here

grammar/KScrLexer.g4

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ STATIC: 'static';
1515
FINAL: 'final';
1616
ABSTRACT: 'abstract';
1717
NATIVE: 'native';
18+
SERVE: 'serve';
1819
SYNCHRONIZED: 'synchronized';
1920

2021
// class types
@@ -23,16 +24,14 @@ INTERFACE: 'interface';
2324
ENUM: 'enum';
2425
ANNOTATION: 'annotation';
2526

26-
// class footprint modifiers
27-
EXTENDS: 'extends';
28-
IMPLEMENTS: 'implements';
29-
3027
// common statements
3128
RETURN: 'return';
3229
THROW: 'throw';
3330
NEW: 'new';
3431
YIELD: 'yield';
3532
IS: 'is';
33+
WHERE: 'where';
34+
SELECT: 'select';
3635

3736
// complex statements
3837
MARK: 'mark';
@@ -58,6 +57,7 @@ ARRAYIDENT: 'array';
5857
TUPLEIDENT: 'tuple';
5958
TYPE: 'type';
6059
NUMIDENT: 'num';
60+
BOOL: 'bool';
6161
BYTE: 'byte';
6262
SHORT: 'short';
6363
INT: 'int';

grammar/KScrParser.g4

Lines changed: 72 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ parser grammar KScrParser;
22

33
options { tokenVocab = KScrLexer; }
44

5+
file: packageDecl imports classDecl* EOF;
6+
57
// file-related
68
packageDecl: PACKAGE id SEMICOLON;
79

@@ -20,10 +22,11 @@ modifier
2022
| STATIC #modStatic
2123
| FINAL #modFinal
2224
| ABSTRACT #modAbstract
23-
| SYNCHRONIZED #modSyncronized
2425
| NATIVE #modNative
26+
| SERVE #modServe
27+
| SYNCHRONIZED #modSyncronized
2528
;
26-
modifiers: modifier*;
29+
modifiers: modifier+;
2730

2831
classType
2932
: CLASS #ctClass
@@ -34,22 +37,44 @@ classType
3437

3538
genericTypeUses: LESSER (n=NUMLIT | first=type) (COMMA type)* GREATER;
3639

37-
type
38-
: idPart #importedTypeName
39-
| rawType genericTypeUses? #normalTypeUse
40-
| rawType genericTypeUses? (indexerEmpty | ELIPSES)? #arrayTypeUse
40+
num: NUMIDENT #numTypeLit
41+
| BOOL #numTypeLitBool
42+
| BYTE #numTypeLitByte
43+
| SHORT #numTypeLitShort
44+
| INT #numTypeLitInt
45+
| LONG #numTypeLitLong
46+
| FLOAT #numTypeLitFloat
47+
| DOUBLE #numTypeLitDouble
48+
;
49+
primitiveTypeLit
50+
: OBJECT #typeLitObject
51+
| ARRAYIDENT #typeLitArray
52+
| TUPLEIDENT #typeLitTuple
53+
| num #typeLitNum
54+
| TYPE #typeLitType
55+
| ENUM #typeLitEnum
56+
| VOID #typeLitVoid
57+
;
58+
primitiveLit
59+
: THIS #varThis
60+
| SUPER #varSuper
61+
| NUMLIT #varLitNum
62+
| TRUE #varLitTrue
63+
| FALSE #varLitFalse
64+
| STRLIT #varLitStr
65+
| STDIOLIT #varLitStdio
66+
| ENDLLIT #varLitEndl
67+
| NULL #varLitNull
4168
;
42-
4369
rawType
4470
: primitiveTypeLit
71+
| idPart
4572
| id
4673
;
74+
type: rawType genericTypeUses? nullable=QUESTION? (indexerEmpty | ELIPSES)? nullableArray=QUESTION?;
4775

4876
genericTypeDef: idPart elp=ELIPSES? (EXTENDS ext=type | SUPER sup=type)? (ASSIGN (defN=NUMLIT | def=type))?;
49-
genericTypeDefs: LESSER (NUMLIT | genericTypeDef) (COMMA genericTypeDef)* GREATER;
50-
51-
objectExtends: EXTENDS type (COMMA type)*;
52-
objectImplements: IMPLEMENTS type (COMMA type)*;
77+
genericDefs: LESSER (NUMLIT | genericTypeDef) (COMMA genericTypeDef)* GREATER;
5378

5479
parameter: FINAL? type idPart (ASSIGN expr)?;
5580
parameters: LPAREN (parameter (COMMA parameter)*)? RPAREN;
@@ -63,7 +88,7 @@ memberExpr: REQARROW uniformBlock;
6388
lambdaBlock: RDASHARROW (uniformBlock | normalBlock);
6489
caseBlock
6590
: COLON statements BREAK SEMICOLON #caseStmtBlock
66-
| memberExpr COMMA #caseExprBlock
91+
| REQARROW memberExpr COMMA #caseExprBlock
6792
;
6893
memberBlock
6994
: normalBlock #memberNormalBlock
@@ -77,40 +102,46 @@ codeBlock
77102
;
78103

79104
initDecl: STATIC memberBlock;
80-
subConstructorCall: type arguments;
105+
subConstructorCall: (THIS | type) arguments;
81106
subConstructorCalls: COLON subConstructorCall (COMMA subConstructorCall)*?;
82-
constructorDecl: annotation* modifiers type parameters subConstructorCalls? memberBlock;
83-
methodDecl: annotation* modifiers genericTypeDefs? type idPart parameters memberBlock;
84-
indexerMemberDecl: annotation* modifiers genericTypeDefs? type THIS indexerDecl propBlock;
85-
86-
propGetter: GET memberBlock;
87-
propSetter: SET memberBlock;
88-
propInit: INIT memberBlock;
107+
constructorDecl: annotation* modifiers? (WHERE condition=expr)? (SELECT supplier=lambda)? (ELSE (NULL | fallback=lambda))?
108+
type parameters subConstructorCalls? memberBlock;
109+
methodDecl: annotation* modifiers? (WHERE condition=expr)? (SELECT supplier=lambda)? (ELSE (NULL | fallback=lambda))?
110+
genericDefs? type idPart parameters genericSpecifiers? memberBlock;
111+
indexerMemberDecl: annotation* modifiers? (WHERE condition=expr)? (SELECT supplier=lambda)? (ELSE (NULL | fallback=lambda))?
112+
genericDefs? type THIS indexerDecl genericSpecifiers? propBlock;
113+
114+
propGetter: GET modifiers? (WHERE condition=expr)? (SELECT supplier=lambda)? (ELSE (NULL | fallback=lambda))? memberBlock;
115+
propSetter: SET modifiers? (WHERE condition=expr)? (SELECT supplier=lambda)? (ELSE (NULL | fallback=lambda))? memberBlock;
116+
propInit: INIT modifiers? (WHERE condition=expr)? (SELECT supplier=lambda)? (ELSE (NULL | fallback=lambda))? memberBlock;
89117
propBlock
90118
: memberBlock #propComputed
91119
| LBRACE propGetter propSetter? propInit? RBRACE #propAccessors
92120
| (ASSIGN expr)? SEMICOLON #propFieldStyle
93121
;
94-
propertyDecl: annotation* modifiers type idPart propBlock;
122+
propertyDecl: annotation* modifiers? (WHERE condition=expr)? (SELECT supplier=lambda)? (ELSE (NULL | fallback=lambda))?
123+
type idPart propBlock;
95124

96125
member
97-
: propertyDecl #memProp
98-
| classDecl #memCls
99-
| initDecl catchBlocks? #memInit
100-
| constructorDecl catchBlocks? #memCtor
101-
| methodDecl catchBlocks? #memMtd
102-
| indexerMemberDecl #memIdx
126+
: propertyDecl #memProp
127+
| classDecl #memCls
128+
| initDecl catchBlocks? #memInit
129+
| constructorDecl catchBlocks? #memCtor
130+
| methodDecl catchBlocks? #memMtd
131+
| indexerMemberDecl #memIdx
132+
| idPart arguments? ASSIGN expr (COMMA | SEMICOLON?) #memEnumConst
103133
;
134+
genericSpecifier: idPart (superclassesDef | (ASSIGN (type | expr)) | superclassesDef (ASSIGN (type | expr)));
135+
genericSpecifiers: WHERE genericSpecifier (COMMA genericSpecifier)*;
136+
superclassesDef: COLON type (COMMA type)*;
104137

105-
classDecl: annotation* modifiers classType idPart genericTypeDefs? objectExtends? objectImplements? (LBRACE member* RBRACE | SEMICOLON);
106-
107-
file: packageDecl imports classDecl* EOF;
138+
classDecl: annotation* modifiers? classType idPart genericDefs? superclassesDef? genericSpecifiers? (LBRACE member* RBRACE | SEMICOLON);
108139

109140
inferType: VOID | VAR;
110141

111-
indexerEmpty: LSQUAR RSQUAR;
112-
indexerDecl: LSQUAR type idPart (COMMA type idPart)* RSQUAR;
113-
indexerExpr: LSQUAR expr (COMMA expr)* RSQUAR;
142+
indexerEmpty: LSQUAR COMMA* RSQUAR;
143+
indexerDecl: (LSQUAR) type idPart (COMMA type idPart)* (RSQUAR);
144+
indexerExpr: (LSQUAR) expr (COMMA expr)* (RSQUAR);
114145
cast: LPAREN type COLON expr RPAREN;
115146
declaration: type idPart (ASSIGN expr)?;
116147
mutation: (binaryop | binaryop_late)? ASSIGN expr;
@@ -120,7 +151,7 @@ newArray: NEW type indexerExpr;
120151
newListedArray: NEW type indexerEmpty LBRACE (expr (COMMA expr)*)? RBRACE;
121152
label: idPart COLON WS;
122153
lambda
123-
: label? type COLON idPart #methodRef
154+
: label? (type COLON)? idPart #methodRef
124155
| label? tupleExpr lambdaBlock #lambdaExpr
125156
;
126157

@@ -153,6 +184,9 @@ statement
153184
| left=expr mutation SEMICOLON #stmtAssign
154185
| left=tupleExpr ASSIGN right=tupleExpr #stmtAssignTuple
155186
| left=expr DOT idPart arguments? #stmtCallMember
187+
| pipe=expr (RREQARROW lambda)+ SEMICOLON #stmtPipeListen
188+
| pipe=expr (RRDASHARROW expr)+ SEMICOLON #stmtPipeRead
189+
| pipe=expr (LLDASHARROW expr)+ SEMICOLON #stmtPipeWrite
156190
| returnStatement SEMICOLON #stmtReturn
157191
| throwStatement SEMICOLON #stmtThrow
158192
| markStatement #stmtMark
@@ -165,17 +199,12 @@ statement
165199
| forStatement catchBlocks? #stmtFor
166200
| foreachStatement catchBlocks? #stmtForeach
167201
| switchStatement catchBlocks? #stmtSwitch
168-
| pipe=expr (RREQARROW lambda)+ SEMICOLON #stmtPipeListen
169-
| pipe=expr (RRDASHARROW expr)+ SEMICOLON #stmtPipeRead
170-
| pipe=expr (LLDASHARROW expr)+ SEMICOLON #stmtPipeWrite
171202
| SEMICOLON #stmtEmpty
172203
;
173204
typedExpr: type? expr;
174205
expr
175-
// simply a variable
176-
: idPart #varValue
177206
// operators
178-
| prefixop expr #opPrefix
207+
: prefixop expr #opPrefix
179208
| left=expr binaryop right=expr #opBinary
180209
| expr postfixop #opPostfix
181210
// `is` keyword
@@ -186,6 +215,8 @@ expr
186215
| LPAREN expr RPAREN #parens
187216
| cond=expr QUESTION left=expr COLON right=expr #ternary
188217
| cast #exprCast
218+
// simply a variable
219+
| idPart #varValue
189220
| newArray #newArrayValue
190221
| newListedArray #newListedArrayValue
191222
| primitiveLit #nativeLitValue
@@ -204,6 +235,7 @@ expr
204235
| left=expr SHORTELIPSES right=expr #rangeInvoc
205236
// pipe operators
206237
| pipe=expr (RREQARROW lambda)+ #exprPipeListen
238+
| pipe=expr (RRDASHARROW expr)+ #exprPipeRead
207239
// tuple expressions
208240
| tupleExpr #exprTuple
209241
| left=expr binaryop_late right=expr #opBinaryLate
@@ -258,35 +290,3 @@ idPart
258290
: ID
259291
| ANNOTATION
260292
;
261-
262-
263-
array: ARRAYIDENT genericTypeUses?;
264-
tuple: TUPLEIDENT genericTypeUses?;
265-
num: (NUMIDENT | INT) genericTypeUses? #numTypeLitTuple
266-
| BYTE #numTypeLitByte
267-
| SHORT #numTypeLitShort
268-
| INT #numTypeLitInt
269-
| LONG #numTypeLitLong
270-
| FLOAT #numTypeLitFloat
271-
| DOUBLE #numTypeLitDouble
272-
;
273-
primitiveTypeLit
274-
: OBJECT #typeLitObject
275-
| array #typeLitArray
276-
| tuple #typeLitTuple
277-
| num #typeLitNum
278-
| TYPE #typeLitType
279-
| ENUM #typeLitEnum
280-
| VOID #typeLitVoid
281-
;
282-
primitiveLit
283-
: THIS #varThis
284-
| SUPER #varSuper
285-
| NUMLIT #varLitNum
286-
| TRUE #varLitTrue
287-
| FALSE #varLitFalse
288-
| STRLIT #varLitStr
289-
| STDIOLIT #varLitStdio
290-
| ENDLLIT #varLitEndl
291-
| NULL #varLitNull
292-
;

kscr-build/Module.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ public void RunBuild()
6565
compileTime = KScrStarter.CompileSource(cmd, cmd.PkgBase);
6666
if (KScrStarter.VM.CompilerErrors.Count > 0)
6767
{
68-
foreach (var error in KScrStarter.VM.CompilerErrors)
69-
log.At(LogLevel.Error, "Compiler Error:\r\n" + error.Message);
70-
throw new Exception("There were Compiler Errors");
68+
KScrStarter.VM.PrintCompilerErrors(log);
69+
log.At(LogLevel.Warning, $"Build {Notation} could not finish due to unresolved compiler errors");
70+
return;
7171
}
7272

7373
ioTime = KScrStarter.WriteClasses(cmd);
@@ -77,7 +77,7 @@ public void RunBuild()
7777
cmd.Output.UpdateMd5(KScrBuild.Md5Path);
7878
log.At(LogLevel.Info, $"Build {Notation} succeeded; {KScrStarter.IOTimeString(compileTime, ioTime: ioTime)}");
7979
Environment.CurrentDirectory = oldwkdir;
80-
}, $"Build failed with exception", LogLevel.Error);
80+
}, "Build failed with exception", LogLevel.Error);
8181
}
8282

8383
public void SaveToFiles(string dir = null!)

kscr-compiler/AbstractVisitor.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ protected AbstractVisitor(CompilerRuntime vm, CompilerContext ctx)
2121
this.ctx = ctx;
2222
}
2323

24-
protected CompilerRuntime vm { get; }
24+
protected internal CompilerRuntime vm { get; }
2525
protected CompilerContext ctx { get; }
2626
protected ITypeInfo? RequestedType { get; init; }
2727

@@ -37,7 +37,7 @@ protected ITypeInfo VisitTypeInfo(KScrParser.TypeContext type)
3737

3838
protected new MemberModifier VisitModifiers(KScrParser.ModifiersContext mods)
3939
{
40-
return new ModifierVisitor().Visit(mods);
40+
return mods == null ? MemberModifier.None : new ModifierVisitor().Visit(mods);
4141
}
4242

4343
protected Operator VisitOperator(ParserRuleContext op)
@@ -55,12 +55,12 @@ protected TypeParameter VisitTypeParameter(KScrParser.GenericTypeDefContext gtd)
5555
: TypeParameterSpecializationType.Extends;
5656
var target = spec switch
5757
{
58-
TypeParameterSpecializationType.List => Core.System.Class.Sequencable.CreateInstance(vm,
59-
Core.System.Class.Sequencable,
60-
Core.System.Class.ObjectType),
58+
TypeParameterSpecializationType.List => Core.System.Class.SequencableType.CreateInstance(vm,
59+
Core.System.Class.SequencableType,
60+
Core.System.Class.VoidType),
6161
TypeParameterSpecializationType.N => Core.System.Class.NumericIntType,
6262
TypeParameterSpecializationType.Extends => gtd.ext == null
63-
? Core.System.Class.ObjectType.DefaultInstance
63+
? Core.System.Class.VoidType.DefaultInstance
6464
: VisitTypeInfo(gtd.ext!),
6565
TypeParameterSpecializationType.Super => VisitTypeInfo(gtd.sup!),
6666
_ => throw new ArgumentOutOfRangeException()

kscr-compiler/Code/ExpressionVisitor.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public override StatementComponent VisitVarAssign(KScrParser.VarAssignContext co
8080
var right = VisitExpression(context.mutation());
8181
var actualType = left.OutputType(vm, ctx);
8282
var varType = right.OutputType(vm, ctx);
83-
if (!actualType.AsClass(vm).CanHold(varType.AsClass(vm)))
83+
if (!actualType.AsClass(vm).IsAssignableFrom(varType.AsClass(vm)))
8484
throw new CompilerException(ToSrcPos(context.mutation().expr()), CompilerErrorMessage.CannotAssign,
8585
actualType, varType);
8686
return new StatementComponent
@@ -165,7 +165,7 @@ public override StatementComponent VisitCtorCall(KScrParser.CtorCallContext cont
165165
SourcefilePosition = ToSrcPos(context)
166166
};
167167
var rtrn = comp.OutputType(vm, ctx);
168-
if (!RequestedType!.AsClass(vm).CanHold(rtrn.AsClass(vm)))
168+
if (!RequestedType!.AsClass(vm).IsAssignableFrom(rtrn.AsClass(vm)))
169169
throw new CompilerException(ToSrcPos(context.type()), CompilerErrorMessage.InvalidType, ctx.Class,
170170
rtrn.FullDetailedName, "Expected derivate of " + RequestedType);
171171
return comp;
@@ -199,7 +199,7 @@ or BytecodeType.LiteralRange or BytecodeType.LiteralNumeric or BytecodeType.Lite
199199
ctx.DropContext();
200200
}
201201

202-
if (!RequestedType!.AsClass(vm).CanHold(rtrn.AsClass(vm)))
202+
if (!RequestedType!.AsClass(vm).IsAssignableFrom(rtrn.AsClass(vm)))
203203
throw new CompilerException(ToSrcPos(context.expr()), CompilerErrorMessage.InvalidType, ctx.Class,
204204
rtrn.FullDetailedName, "Expected derivate of " + RequestedType);
205205
return expr;
@@ -216,7 +216,7 @@ public override StatementComponent VisitThrowStatement(KScrParser.ThrowStatement
216216
SourcefilePosition = ToSrcPos(context)
217217
};
218218
var rtrn = comp.OutputType(vm, ctx);
219-
if (!Core.System.Class.ThrowableType.CanHold(rtrn.AsClass(vm)))
219+
if (!Core.System.Class.ThrowableType.IsAssignableFrom(rtrn.AsClass(vm)))
220220
throw new CompilerException(ToSrcPos(context.expr()), CompilerErrorMessage.InvalidType, ctx.Class,
221221
rtrn.FullDetailedName, "Expected derivate of Throwable");
222222
return comp;

0 commit comments

Comments
 (0)