Skip to content

Commit

Permalink
Type checking, sub-selectors, correct types
Browse files Browse the repository at this point in the history
  • Loading branch information
Vilsol committed Apr 8, 2021
1 parent 9038703 commit a629348
Show file tree
Hide file tree
Showing 46 changed files with 1,836 additions and 1,451 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ There are several example programs available on [the wiki](https://github.com/Vi
* Multi-pass pre/post-processing
* Stackless functions
* Comment generation including source mapping
* Sub-selector support
* Type checking

## Roadmap

* Full variable block scoping
* Nested sub-selector support

## Planned Optimizations

Expand Down
71 changes: 71 additions & 0 deletions checker/importer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package checker

import (
"fmt"
"go/types"
)

type Importer struct {
packages map[string]*types.Package
}

func New() *Importer {
return &Importer{
packages: make(map[string]*types.Package),
}
}

var importing types.Package

func (p *Importer) Import(path string) (*types.Package, error) {
pkg := p.packages[path]
if pkg != nil {
if pkg == &importing {
return nil, fmt.Errorf("import cycle through package %q", path)
}
if !pkg.Complete() {
return pkg, fmt.Errorf("reimported partially imported package %q", path)
}
return pkg, nil
}

p.packages[path] = &importing
defer func() {
if p.packages[path] == &importing {
p.packages[path] = nil
}
}()

var firstHardErr error
conf := types.Config{
IgnoreFuncBodies: true,
Error: func(err error) {
if firstHardErr == nil && !err.(types.Error).Soft {
firstHardErr = err
}
},
Importer: p,
}

pack := FindPackage(path)

if pack == nil {
return nil, fmt.Errorf("package not found %q", path)
}

pkg, err := conf.Check(path, GetFset(), pack, nil)
if err != nil {
if firstHardErr != nil {
pkg = nil
err = firstHardErr
}
return pkg, fmt.Errorf("type-checking package %q failed (%v)", path, err)
}

if firstHardErr != nil {
panic("package is not safe yet no error was returned")
}

p.packages[path] = pkg
return pkg, nil
}
35 changes: 35 additions & 0 deletions checker/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package checker

import (
"go/ast"
"go/parser"
"go/token"
)

var packages = make(map[string][]*ast.File)
var registryFset = token.NewFileSet()

func RegisterPackages(path string, files map[string]string) {
asts := make([]*ast.File, 0)

for name, file := range files {
f, err := parser.ParseFile(registryFset, name, file, 0)
if err != nil {
panic(err)
}
if f.Imports != nil || len(f.Imports) > 0 {
continue
}
asts = append(asts, f)
}

packages[path] = asts
}

func FindPackage(path string) []*ast.File {
return packages[path]
}

func GetFset() *token.FileSet {
return registryFset
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module github.com/Vilsol/go-mlog

go 1.15
go 1.16

require (
github.com/olekukonko/tablewriter v0.0.5
github.com/sirupsen/logrus v1.8.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.1.3
github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.7.0
Expand Down
18 changes: 2 additions & 16 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,10 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
Expand All @@ -135,8 +131,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
Expand All @@ -163,10 +157,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
Expand All @@ -177,8 +169,6 @@ github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
Expand All @@ -190,10 +180,8 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
Expand Down Expand Up @@ -323,8 +311,6 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
Expand Down
173 changes: 1 addition & 172 deletions m/base.go
Original file line number Diff line number Diff line change
@@ -1,153 +1,5 @@
package m

import (
"errors"
"github.com/Vilsol/go-mlog/transpiler"
"strings"
)

func init() {
transpiler.RegisterFuncTranslation("m.Read", transpiler.Translator{
Count: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) int {
return 1
},
Variables: 1,
Translate: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) ([]transpiler.MLOGStatement, error) {
memoryName := strings.Trim(args[0].GetValue(), "\"")

// TODO Remove hardcode
if memoryName == "bank1" {
return nil, errors.New("can't read/write to memory cell that is used for the stack: bank1")
}

return []transpiler.MLOGStatement{
&transpiler.MLOG{
Statement: [][]transpiler.Resolvable{
{
&transpiler.Value{Value: "read"},
vars[0],
&transpiler.Value{Value: memoryName},
&transpiler.Value{Value: args[1].GetValue()},
},
},
},
}, nil
},
})
write := transpiler.Translator{
Count: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) int {
return 1
},
Translate: func(args []transpiler.Resolvable, _ []transpiler.Resolvable) ([]transpiler.MLOGStatement, error) {
memoryName := strings.Trim(args[1].GetValue(), "\"")

if memoryName == "bank1" {
return nil, errors.New("can't read/write to memory cell that is used for the stack: bank1")
}

return []transpiler.MLOGStatement{
&transpiler.MLOG{
Statement: [][]transpiler.Resolvable{
{
&transpiler.Value{Value: "write"},
&transpiler.Value{Value: args[0].GetValue()},
&transpiler.Value{Value: memoryName},
&transpiler.Value{Value: args[2].GetValue()},
},
},
},
}, nil
},
}
transpiler.RegisterFuncTranslation("m.Write", write)
transpiler.RegisterFuncTranslation("m.WriteInt", write)
transpiler.RegisterFuncTranslation("m.PrintFlush", transpiler.Translator{
Count: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) int {
return 1
},
Translate: func(args []transpiler.Resolvable, _ []transpiler.Resolvable) ([]transpiler.MLOGStatement, error) {
return []transpiler.MLOGStatement{
&transpiler.MLOG{
Statement: [][]transpiler.Resolvable{
{
&transpiler.Value{Value: "printflush"},
&transpiler.Value{Value: strings.Trim(args[0].GetValue(), "\"")},
},
},
},
}, nil
},
})
transpiler.RegisterFuncTranslation("m.GetLink", transpiler.Translator{
Count: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) int {
return 1
},
Variables: 1,
Translate: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) ([]transpiler.MLOGStatement, error) {
return []transpiler.MLOGStatement{
&transpiler.MLOG{
Statement: [][]transpiler.Resolvable{
{
&transpiler.Value{Value: "getlink"},
vars[0],
&transpiler.Value{Value: args[0].GetValue()},
},
},
},
}, nil
},
})
transpiler.RegisterFuncTranslation("m.Radar", transpiler.Translator{
Count: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) int {
return 1
},
Variables: 1,
Translate: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) ([]transpiler.MLOGStatement, error) {
return []transpiler.MLOGStatement{
&transpiler.MLOG{
Statement: [][]transpiler.Resolvable{
{
&transpiler.Value{Value: "radar"},
&transpiler.Value{Value: args[1].GetValue()},
&transpiler.Value{Value: args[2].GetValue()},
&transpiler.Value{Value: args[3].GetValue()},
&transpiler.Value{Value: args[5].GetValue()},
&transpiler.Value{Value: args[0].GetValue()},
&transpiler.Value{Value: args[4].GetValue()},
vars[0],
},
},
},
}, nil
},
})
transpiler.RegisterFuncTranslation("m.Sensor", transpiler.Translator{
Count: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) int {
return 1
},
Variables: 1,
Translate: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) ([]transpiler.MLOGStatement, error) {
return []transpiler.MLOGStatement{
&transpiler.MLOG{
Statement: [][]transpiler.Resolvable{
{
&transpiler.Value{Value: "sensor"},
vars[0],
&transpiler.Value{Value: strings.Trim(args[0].GetValue(), "\"")},
&transpiler.Value{Value: strings.Trim(args[1].GetValue(), "\"")},
},
},
},
}, nil
},
})

transpiler.RegisterFuncTranslation("GetHealth", createSensorFuncTranslation("@health"))
transpiler.RegisterFuncTranslation("GetName", createSensorFuncTranslation("@name"))
transpiler.RegisterFuncTranslation("GetX", createSensorFuncTranslation("@x"))
transpiler.RegisterFuncTranslation("GetY", createSensorFuncTranslation("@y"))
}

// Read a float64 value from memory at specified position
func Read(memory string, position int) int {
return 0
Expand Down Expand Up @@ -177,34 +29,11 @@ func GetLink(address int) Link {
// Retrieve a list of units that match specified conditions
//
// Conditions are combined using an `and` operation
func Radar(from Building, target1 RadarTarget, target2 RadarTarget, target3 RadarTarget, sortOrder bool, sort RadarSort) Unit {
func Radar(from Ranged, target1 RadarTarget, target2 RadarTarget, target3 RadarTarget, sortOrder bool, sort RadarSort) Unit {
return nil
}

// Extract information indicated by sense from the provided block
func Sensor(block HealthC, sense string) float64 {
return 0
}

func createSensorFuncTranslation(attribute string) transpiler.Translator {
return transpiler.Translator{
Count: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) int {
return 1
},
Variables: 1,
Translate: func(args []transpiler.Resolvable, vars []transpiler.Resolvable) ([]transpiler.MLOGStatement, error) {
return []transpiler.MLOGStatement{
&transpiler.MLOG{
Statement: [][]transpiler.Resolvable{
{
&transpiler.Value{Value: "sensor"},
vars[0],
&transpiler.Value{Value: strings.Trim(args[0].GetValue(), "\"")},
&transpiler.Value{Value: attribute},
},
},
},
}, nil
},
}
}
Loading

0 comments on commit a629348

Please sign in to comment.