Skip to content

Commit

Permalink
feat » test
Browse files Browse the repository at this point in the history
  • Loading branch information
pontaoski committed Dec 12, 2021
1 parent dea27b4 commit 3f24bee
Show file tree
Hide file tree
Showing 24 changed files with 368 additions and 21 deletions.
7 changes: 0 additions & 7 deletions kompilierer/ast/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package ast
import (
"fmt"
"io"
"strings"
"text/scanner"

"github.com/alecthomas/participle/v2/lexer"
Expand Down Expand Up @@ -63,12 +62,6 @@ func (l *lexFac) Lex(f string, r io.Reader) (lexer.Lexer, error) {
file: f,
scanner: s,
}
lex.scanner.Error = func(s *scanner.Scanner, msg string) {
// This is to support single quoted strings. Hacky.
if !strings.HasSuffix(msg, "char literal") {
lex.err = errorf(lexer.Position(lex.scanner.Pos()), msg)
}
}

return lex, nil
}
Expand Down
1 change: 1 addition & 0 deletions kompilierer/ast/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ type Typkonstruktor struct {
var (
Parser = participle.MustBuild(&Modul{}, participle.UseLookahead(4), participle.Lexer(&lexFac{}), participle.Elide("Comment"))
TerminalParser = participle.MustBuild(&Terminal{}, participle.UseLookahead(4), participle.Lexer(&lexFac{}), participle.Elide("Comment"))
deklParser = participle.MustBuild(&Deklaration{}, participle.UseLookahead(4), participle.Lexer(&lexFac{}), participle.Elide("Comment"))
argListeParser = participle.MustBuild(&Argumentliste{}, participle.UseLookahead(4), participle.Lexer(&lexFac{}), participle.Elide("Comment"))
typFunktionParser = participle.MustBuild(&Typfunktion{}, participle.UseLookahead(4), participle.Lexer(&lexFac{}), participle.Elide("Comment"))
funktionsLiteralParser = participle.MustBuild(&Funktionsliteral{}, participle.UseLookahead(4), participle.Lexer(&lexFac{}), participle.Elide("Comment"))
Expand Down
45 changes: 45 additions & 0 deletions kompilierer/ast/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,51 @@ func TestFunk(t *testing.T) {
}
}

func TestParens(t *testing.T) {
var v Terminal
feh := TerminalParser.ParseString("mald", "sei x = 1 == (2 == 3) in 1", &v)
if feh != nil {
t.Fatalf("error: %s", feh)
}
}

func TestFirstClassCall(t *testing.T) {
var v Terminal
feh := TerminalParser.ParseString("mald", "sei x = a.(2 == 3) in 1", &v)
if feh != nil {
t.Fatalf("error: %s", feh)
}
}

func TestNonassoc(t *testing.T) {
var v Terminal
feh := TerminalParser.ParseString("mald", "sei x = a == b == c in 1", &v)
if feh == nil {
t.Fatalf("wanted error, got none")
}
}

func TestDeclarations(t *testing.T) {
var d Deklaration
feh := deklParser.ParseString("mald", `/* mald */ funk A() => 1`, &d)
if feh != nil {
t.Fatalf("error: %s", feh)
}
if d.Comments() != "mald" {
t.Fatalf("expected: %s, got: %s", "mald", d.Comments())
}

feh = deklParser.ParseString("mald",
`// mald
funk A() => 1`, &d)
if feh != nil {
t.Fatalf("error: %s", feh)
}
if d.Comments() != "mald" {
t.Fatalf("expected: %s, got: %s", "mald", d.Comments())
}
}

func TestFunktionsLiteral(t *testing.T) {
var v Funktionsliteral
feh := funktionsLiteralParser.ParseString("mald", "\\(x: Logik) => x", &v)
Expand Down
6 changes: 4 additions & 2 deletions kompilierer/fehlerberichtung/fehlerberichtung.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ import (
"Tawa/kompilierer/getypisiertast"
"fmt"
"strings"

"github.com/ztrue/tracerr"
)

func GleichErr(span getypisiertast.Span, art string, a getypisiertast.ITyp, b getypisiertast.ITyp) error {
return NeuFehler(span, "%s nicht gleich: »%s« »%s«", art, a, b)
}

func NeuFehler(span getypisiertast.Span, format string, a ...interface{}) error {
return PositionError{
return tracerr.Wrap(PositionError{
Text: fmt.Sprintf(format, a...),
Span: span,
}
})
}

type PositionError struct {
Expand Down
6 changes: 3 additions & 3 deletions kompilierer/getypisiertast/getypisiertast.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,12 +310,12 @@ func (v Pattern) Pos() Span { return v.LPos }
type Liste struct {
Werte []Expression

LTyp ITyp
LPos Span
ElTyp ITyp
LPos Span
}

func (v Liste) istExpression() {}
func (v Liste) Typ() ITyp { return v.LTyp }
func (v Liste) Typ() ITyp { return TypListe(v.ElTyp) }
func (v Liste) Pos() Span { return v.LPos }

type Muster struct {
Expand Down
49 changes: 49 additions & 0 deletions kompilierer/typisierung/bidi.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,55 @@ func substituteExpression(expr getypisiertast.Expression, suche getypisiertast.I
case getypisiertast.Nativ:
v.LTyp = substitute(v.LTyp, suche, ersetzen)
return v
case getypisiertast.ValBinaryOperator:
v.LTyp = substitute(v.LTyp, suche, ersetzen)
v.Links = substituteExpression(v.Links, suche, ersetzen)
v.Rechts = substituteExpression(v.Rechts, suche, ersetzen)
return v
case getypisiertast.Feldzugriff:
v.LTyp = substitute(v.LTyp, suche, ersetzen)
v.Links = substituteExpression(v.Links, suche, ersetzen)
return v
case getypisiertast.FunktionErsteKlasseAufruf:
v.Funktion = substituteExpression(v.Funktion, suche, ersetzen)
for idx, expr := range v.Argumenten {
v.Argumenten[idx] = substituteExpression(expr, suche, ersetzen)
}
v.Rückgabetyp = substitute(v.Rückgabetyp, suche, ersetzen)
return v
case getypisiertast.Sei:
v.Wert = substituteExpression(v.Wert, suche, ersetzen)
v.In = substituteExpression(v.In, suche, ersetzen)
if v.MussTyp == nil {
panic("e")
}
v.MussTyp = substitute(v.MussTyp, suche, ersetzen)
return v
case getypisiertast.Funktionsliteral:
v.LTyp = substitute(v.LTyp, suche, ersetzen).(getypisiertast.Typfunktion)
v.Expression = substituteExpression(v.Expression, suche, ersetzen)
for idx, fv := range v.Formvariabeln {
v.Formvariabeln[idx].Typ = substitute(fv.Typ, suche, ersetzen)
}
return v
case getypisiertast.Liste:
v.ElTyp = substitute(v.ElTyp, suche, ersetzen)
for idx, fv := range v.Werte {
v.Werte[idx] = substituteExpression(fv, suche, ersetzen)
}
return v
case getypisiertast.Strukturaktualisierung:
v.Wert = substituteExpression(v.Wert, suche, ersetzen)
for idx, fv := range v.Felden {
v.Felden[idx].Wert = substituteExpression(fv.Wert, suche, ersetzen)
}
return v
case getypisiertast.LogikBinaryOperator:
v.Links = substituteExpression(v.Links, suche, ersetzen)
v.Rechts = substituteExpression(v.Rechts, suche, ersetzen)
return v
case getypisiertast.Zeichenkette:
return v
default:
panic("e " + repr.String(v))
}
Expand Down
21 changes: 13 additions & 8 deletions kompilierer/typisierung/bidi_getypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func checkGetypisiertExpression(l *lokalekontext, s *scopes, expr getypisiertast
case getypisiertast.Liste:
var (
werte []getypisiertast.Expression
typ getypisiertast.ITyp = e.LTyp
typ getypisiertast.ITyp = e.ElTyp
)
if _, ok := typ.(getypisiertast.Nichtunifiziert); ok {
typ = nil
Expand All @@ -34,20 +34,19 @@ func checkGetypisiertExpression(l *lokalekontext, s *scopes, expr getypisiertast
werte = append(werte, wert)
}
}
ltyp := getypisiertast.TypListe(typ)
if typ == nil {
switch t := gegenTyp.(type) {
case getypisiertast.Typnutzung:
if t.SymbolURL == getypisiertast.TypListURL {
ltyp = t
typ = t
}
default:
return nil, fehlerberichtung.NeuFehler(e.Pos(), "was zum fick")
}
}
return getypisiertast.Liste{
Werte: werte,
LTyp: ltyp,
ElTyp: typ,
LPos: e.LPos,
}, nil
case getypisiertast.Funktionsliteral:
Expand Down Expand Up @@ -372,7 +371,7 @@ func synthGetypisiertExpression(l *lokalekontext, s *scopes, expr getypisiertast
case getypisiertast.Liste:
var (
werte []getypisiertast.Expression
typ getypisiertast.ITyp = e.LTyp
typ getypisiertast.ITyp = e.ElTyp
)
if _, ok := typ.(getypisiertast.Nichtunifiziert); ok {
typ = nil
Expand All @@ -398,7 +397,7 @@ func synthGetypisiertExpression(l *lokalekontext, s *scopes, expr getypisiertast
}
return getypisiertast.Liste{
Werte: werte,
LTyp: getypisiertast.TypListe(typ),
ElTyp: typ,
LPos: e.LPos,
}, nil
case getypisiertast.Nativ:
Expand All @@ -418,6 +417,7 @@ func synthGetypisiertExpression(l *lokalekontext, s *scopes, expr getypisiertast
return nil, feh
}
neuer.LPos = e.LPos
neuer.MussTyp = getypisiertast.Nichtunifiziert{}

s.neuScope()
s.head().vars[neuer.Name] = neuer.Wert.Typ()
Expand Down Expand Up @@ -531,8 +531,13 @@ func typiereFunktionsliteral(l *lokalekontext, s *scopes, e getypisiertast.Funkt
if feh != nil {
return nil, feh
}
if !TypGleich(rückgabe.Typ(), e.LTyp.Rückgabetyp) && !TypGleich(e.LTyp.Rückgabetyp, getypisiertast.TypEinheit) {
return nil, fehlerberichtung.NeuFehler(e.Expression.Pos(), "Das Funktionssignatur sagt das diese Funktion züruck %s gibt, aber es gibt %s züruck.", e.LTyp.Rückgabetyp, rückgabe.Typ())

if _, ok := e.LTyp.Rückgabetyp.(getypisiertast.Nichtunifiziert); ok && erwartete == nil {
e.LTyp.Rückgabetyp = rückgabe.Typ()
} else {
if !TypGleich(rückgabe.Typ(), e.LTyp.Rückgabetyp) && !TypGleich(e.LTyp.Rückgabetyp, getypisiertast.TypEinheit) {
return nil, fehlerberichtung.NeuFehler(e.Expression.Pos(), "Das Funktionssignatur sagt das diese Funktion züruck %s gibt, aber es gibt %s züruck.", e.LTyp.Rückgabetyp, rückgabe.Typ())
}
}

e.Expression = rückgabe
Expand Down
73 changes: 73 additions & 0 deletions kompilierer/typisierung/bidi_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package typisierung

import (
"Tawa/kompilierer/ast"
"Tawa/kompilierer/fehlerberichtung"
"embed"
"testing"

"github.com/ztrue/tracerr"
)

//go:embed test/*
var testDateien embed.FS

func TestDateien(t *testing.T) {
files, feh := testDateien.ReadDir("test/erwarte-gut")
if feh != nil {
panic("fehler: " + feh.Error())
}
for _, datei := range files {
k := NeuKontext()

data, feh := testDateien.ReadFile("test/erwarte-gut/" + datei.Name())
t.Log(datei.Name())
if feh != nil {
panic("fehler: " + feh.Error())
}

modul := ast.Modul{}
feh = ast.Parser.ParseBytes(datei.Name(), data, &modul)
if feh != nil {
panic(feh)
}

_, feh = zuGetypisierteAst(k, "Tawa", modul)
if feh != nil {
v, ok := feh.(fehlerberichtung.VerketteterFehler)
if ok {
for _, it := range v.Fehler {
t.Logf("%s", tracerr.Sprint(it))
}
} else {
t.Logf("%s", tracerr.Sprint(feh))
}
t.FailNow()
}
}
files, feh = testDateien.ReadDir("test/erwarte-schlecht")
if feh != nil {
panic("fehler: " + feh.Error())
}
for _, datei := range files {
k := NeuKontext()

data, feh := testDateien.ReadFile("test/erwarte-schlecht/" + datei.Name())
t.Log(datei.Name())
if feh != nil {
panic("fehler: " + feh.Error())
}

modul := ast.Modul{}
feh = ast.Parser.ParseBytes(datei.Name(), data, &modul)
if feh != nil {
panic(feh)
}

_, feh = zuGetypisierteAst(k, "Tawa", modul)
if feh == nil {
t.Fatalf("fehler erwartet")
}
println(feh.Error())
}
}
2 changes: 1 addition & 1 deletion kompilierer/typisierung/namensauflösung.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func exprNamensauflösung(k *Kontext, s *scopes, l *lokalekontext, astExpr ast.E

return getypisiertast.Liste{
Werte: expressionen,
LTyp: lTyp,
ElTyp: lTyp,
LPos: lPos,
}, nil
} else if terminal.Funktionsaufruf != nil {
Expand Down
11 changes: 11 additions & 0 deletions kompilierer/typisierung/test/erwarte-gut/00-annotation.tawa
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
paket Haupt zeigt alles

funk Annotation()
Debuggen:druck(
Liste:map([1, 2, 3], \(x: Ganz): Ganz => x + 1)
)

funk KeinAnnotation()
Debuggen:druck(
Liste:map([1, 2, 3], \(x) => x + 1)
)
4 changes: 4 additions & 0 deletions kompilierer/typisierung/test/erwarte-gut/01-einheit.tawa
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
paket Haupt zeigt alles

funk IstEinheit(): Einheit
Debuggen:druck("jo!")
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
paket Haupt zeigt alles

funk Annotation(): Ganz
sei x = \(x: Ganz) => x + 1 in
x.(5)
9 changes: 9 additions & 0 deletions kompilierer/typisierung/test/erwarte-gut/03-liste.tawa
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
paket Haupt zeigt alles

funk Liste1()
sei x = [1] in
x

funk Liste2()
sei x: Liste[Ganz] = [] in
x
15 changes: 15 additions & 0 deletions kompilierer/typisierung/test/erwarte-gut/04-strukt.tawa
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
paket Strukt zeigt nichts

typ Struktur ist
a: Ganz
b: Ganz
beende

funk NeuStruktur(): Struktur
#Struktur { a = 5, b = 50 }

funk NeuerStruktur(): Struktur
{ NeuStruktur() | a = 5, b = 3 }

funk WasIst(a: Struktur): Ganz
a.a
13 changes: 13 additions & 0 deletions kompilierer/typisierung/test/erwarte-gut/05-comp.tawa
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
paket Haupt zeigt nichts

funk Comp1()
1 < 2

funk Comp2()
1 > 2

funk Comp3()
1 >= 2

funk Comp4()
1 <= 2
4 changes: 4 additions & 0 deletions kompilierer/typisierung/test/erwarte-gut/06-verketten.tawa
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
paket Haupt zeigt nichts

funk Verketten1()
[1] ++ [2]
Loading

0 comments on commit 3f24bee

Please sign in to comment.