Skip to content

Commit 874b489

Browse files
authored
Merge pull request #121 from DDP-Projekt/transitive-assigneable-casts
Transitive Casts als Assigneables
2 parents 53c260b + dd4464a commit 874b489

File tree

14 files changed

+322
-121
lines changed

14 files changed

+322
-121
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Der Changelog von DDP. Sortiert nach Release.
1111

1212
## In Entwicklung
1313

14+
- [Neu] Typanpassende Ausdrücke können nun als Referenzen übergeben werden, solange sie nur Typaliase bzw. Typdefinitionen behandeln
1415
- [Fix] Bug im Kompilierer, bei dem VTables für primitive Typen falsch generiert wurden
1516
- [Fix] Bug in Duden/Listen -> Elementweise_Quotient_Kommazahl wurde in der generischen Implementation behoben
1617
- [Breaking] Duden/Sortierung, Duden/HashTabelle und Duden/Listen verwenden nun generische Funktionen und Kombinationen

src/ast/annotators/const_func_param.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ func doesReferenceVarMutable(expr ast.Expression, decls []*ast.VarDecl) []*ast.V
148148
return doesReferenceVarMutable(ass.Lhs, decls)
149149
case *ast.FieldAccess:
150150
return doesReferenceVarMutable(ass.Rhs, decls)
151+
case *ast.CastAssigneable:
152+
return doesReferenceVarMutable(ass.Lhs, decls)
151153
default:
152154
return decls // better safe than sorry
153155
}

src/ast/expressions.go

Lines changed: 133 additions & 118 deletions
Large diffs are not rendered by default.

src/ast/helper_visitor.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,14 @@ func (h *helperVisitor) VisitCastExpr(expr *CastExpr) VisitResult {
352352
return h.visitChildren(result, expr.Lhs)
353353
}
354354

355+
func (h *helperVisitor) VisitCastAssigneable(expr *CastAssigneable) VisitResult {
356+
result := VisitRecurse
357+
if vis, ok := h.actualVisitor.(CastAssigneableVisitor); ok {
358+
result = vis.VisitCastAssigneable(expr)
359+
}
360+
return h.visitChildren(result, expr.Lhs)
361+
}
362+
355363
func (h *helperVisitor) VisitTypeOpExpr(expr *TypeOpExpr) VisitResult {
356364
result := VisitRecurse
357365
if vis, ok := h.actualVisitor.(TypeOpExprVisitor); ok {

src/ast/printer.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,11 @@ func (pr *printer) VisitCastExpr(expr *CastExpr) VisitResult {
235235
return VisitRecurse
236236
}
237237

238+
func (pr *printer) VisitCastAssigneable(expr *CastAssigneable) VisitResult {
239+
pr.parenthesizeNode(fmt.Sprintf("CastAssigneable[%s]", expr.TargetType), expr.Lhs)
240+
return VisitRecurse
241+
}
242+
238243
func (pr *printer) VisitTypeOpExpr(expr *TypeOpExpr) VisitResult {
239244
pr.parenthesizeNode(fmt.Sprintf("TypeOpExpr[%s]: %s", expr.Operator, expr.Rhs))
240245
return VisitRecurse

src/ast/visitor.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type FullVisitor interface {
5151
BinaryExprVisitor
5252
TernaryExprVisitor
5353
CastExprVisitor
54+
CastAssigneableVisitor
5455
TypeOpExprVisitor
5556
TypeCheckVisitor
5657
GroupingVisitor
@@ -166,6 +167,10 @@ type (
166167
Visitor
167168
VisitCastExpr(*CastExpr) VisitResult
168169
}
170+
CastAssigneableVisitor interface {
171+
Visitor
172+
VisitCastAssigneable(*CastAssigneable) VisitResult
173+
}
169174
TypeOpExprVisitor interface {
170175
Visitor
171176
VisitTypeOpExpr(*TypeOpExpr) VisitResult
@@ -442,6 +447,15 @@ func (f CastExprVisitorFunc) VisitCastExpr(expr *CastExpr) VisitResult {
442447
return f(expr)
443448
}
444449

450+
type CastAssigneableVisitorFunc func(*CastAssigneable) VisitResult
451+
452+
var _ CastAssigneableVisitor = (CastAssigneableVisitorFunc)(nil)
453+
454+
func (CastAssigneableVisitorFunc) Visitor() {}
455+
func (f CastAssigneableVisitorFunc) VisitCastAssigneable(expr *CastAssigneable) VisitResult {
456+
return f(expr)
457+
}
458+
445459
type TypeOpExprVisitorFunc func(*TypeOpExpr) VisitResult
446460

447461
var _ TypeOpExprVisitor = (TypeOpExprVisitorFunc)(nil)

src/compiler/compiler.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,6 +1795,11 @@ func (c *compiler) VisitCastExpr(e *ast.CastExpr) ast.VisitResult {
17951795
return ast.VisitRecurse
17961796
}
17971797

1798+
func (c *compiler) VisitCastAssigneable(e *ast.CastAssigneable) ast.VisitResult {
1799+
c.evaluate(&ast.CastExpr{Lhs: e.Lhs, TargetType: e.TargetType, Range: e.Range})
1800+
return ast.VisitRecurse
1801+
}
1802+
17981803
func (c *compiler) VisitTypeOpExpr(e *ast.TypeOpExpr) ast.VisitResult {
17991804
switch e.Operator {
18001805
case ast.TYPE_SIZE:
@@ -1879,6 +1884,8 @@ func (c *compiler) evaluateAssignableOrReference(ass ast.Assigneable, as_ref boo
18791884
} else {
18801885
c.err("non-struct type passed to FieldAccess")
18811886
}
1887+
case *ast.CastAssigneable:
1888+
return c.evaluateAssignableOrReference(assign.Lhs, as_ref)
18821889
}
18831890
c.err("Invalid types in evaluateAssignableOrReference %s", ass)
18841891
return nil, nil, nil

src/parser/expressions.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,17 @@ func (p *parser) assigneable() ast.Assigneable {
781781
}
782782
var ass ast.Assigneable = ident
783783

784+
for p.matchAny(token.ALS) {
785+
ass = &ast.CastAssigneable{
786+
Range: token.Range{
787+
Start: ass.GetRange().Start,
788+
End: token.NewEndPos(p.previous()),
789+
},
790+
TargetType: p.parseType(false),
791+
Lhs: ass,
792+
}
793+
}
794+
784795
for p.matchAny(token.VON) {
785796
if p.matchAny(token.IDENTIFIER) {
786797
rhs := assigneable_impl(true)
@@ -801,7 +812,7 @@ func (p *parser) assigneable() ast.Assigneable {
801812
if !isInFieldAcess {
802813
for p.matchAny(token.AN) {
803814
p.consumeSeq(token.DER, token.STELLE)
804-
index := p.unary() // TODO: check if this can stay p.expression or if p.unary is better
815+
index := p.unary()
805816
ass = &ast.Indexing{
806817
Lhs: ass,
807818
Index: index,

src/parser/resolver/resolver.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,11 @@ func (r *Resolver) VisitCastExpr(expr *ast.CastExpr) ast.VisitResult {
285285
return ast.VisitRecurse
286286
}
287287

288+
func (r *Resolver) VisitCastAssigneable(expr *ast.CastAssigneable) ast.VisitResult {
289+
r.visit(expr.Lhs) // visit the actual expressions
290+
return ast.VisitRecurse
291+
}
292+
288293
func (r *Resolver) VisitTypeOpExpr(expr *ast.TypeOpExpr) ast.VisitResult {
289294
return ast.VisitRecurse
290295
}
@@ -372,6 +377,8 @@ func (r *Resolver) VisitAssignStmt(stmt *ast.AssignStmt) ast.VisitResult {
372377
r.visit(assign.Index)
373378
case *ast.FieldAccess:
374379
r.visit(assign.Rhs)
380+
case *ast.CastAssigneable:
381+
r.visit(assign.Lhs)
375382
}
376383
r.visit(stmt.Rhs)
377384
return ast.VisitRecurse

src/parser/typechecker/assignable_checker.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,24 @@ func isAssignable(expr ast.Expression) (ast.Assigneable, bool) {
1616
return isAssignable(ass.Expr)
1717
case *ast.BinaryExpr:
1818
return isBinaryExprAssignable(ass)
19+
case *ast.CastExpr:
20+
// overloaded expressions cannot be assignables
21+
if ass.OverloadedBy != nil {
22+
return nil, false
23+
}
24+
25+
return isAssignable(ass.Lhs)
1926
default:
2027
return nil, false
2128
}
2229
}
2330

2431
func isBinaryExprAssignable(expr *ast.BinaryExpr) (ast.Assigneable, bool) {
32+
// overloaded expressions cannot be assignables
33+
if expr.OverloadedBy != nil {
34+
return nil, false
35+
}
36+
2537
switch expr.Operator {
2638
case ast.BIN_FIELD_ACCESS:
2739
ident, isIdent := expr.Lhs.(*ast.Ident)
@@ -44,8 +56,6 @@ func isBinaryExprAssignable(expr *ast.BinaryExpr) (ast.Assigneable, bool) {
4456
Index: expr.Rhs,
4557
}, true
4658
}
47-
default:
48-
return nil, false
4959
}
5060
return nil, false
5161
}

0 commit comments

Comments
 (0)