From 33876effde6cfb00957fd7739249f51068ae1838 Mon Sep 17 00:00:00 2001 From: Vilsol Date: Thu, 7 Jan 2021 06:51:20 +0200 Subject: [PATCH] Allow string function parameters, add constant function --- cmd/root.go | 7 +++++-- cmd/transpile.go | 8 +++++--- m/custom.go | 36 ++++++++++++++++++++++++++++++++++++ transpiler/main.go | 12 +++++++++--- transpiler/options.go | 10 ++++++---- transpiler/type_base.go | 3 +++ transpiler/type_function.go | 10 ++++++++++ transpiler/type_mlog.go | 19 +++++++++++++++++++ transpiler/type_native.go | 25 +++++++++++++++---------- transpiler/types.go | 3 ++- 10 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 m/custom.go diff --git a/cmd/root.go b/cmd/root.go index be3bf33..9a8b76c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -54,8 +54,9 @@ func init() { rootCmd.PersistentFlags().Bool("numbers", false, "Output line numbers") rootCmd.PersistentFlags().Bool("comments", false, "Output comments") - rootCmd.PersistentFlags().Bool("debug", false, "Write to debug memory cell") + rootCmd.PersistentFlags().Int("comment-offset", 50, "Comment offset from line start") rootCmd.PersistentFlags().String("stacked", "", "Use a provided memory cell/bank as a stack") + rootCmd.PersistentFlags().Bool("source", false, "Output source code after comment") rootCmd.PersistentFlags().String("output", "", "Output file. Outputs to stdout if unspecified") @@ -64,7 +65,9 @@ func init() { _ = viper.BindPFlag("numbers", rootCmd.PersistentFlags().Lookup("numbers")) _ = viper.BindPFlag("comments", rootCmd.PersistentFlags().Lookup("comments")) - _ = viper.BindPFlag("debug", rootCmd.PersistentFlags().Lookup("debug")) + _ = viper.BindPFlag("comment-offset", rootCmd.PersistentFlags().Lookup("comment-offset")) + _ = viper.BindPFlag("stacked", rootCmd.PersistentFlags().Lookup("stacked")) + _ = viper.BindPFlag("source", rootCmd.PersistentFlags().Lookup("source")) _ = viper.BindPFlag("output", rootCmd.PersistentFlags().Lookup("output")) } diff --git a/cmd/transpile.go b/cmd/transpile.go index 8956ff0..97e4323 100644 --- a/cmd/transpile.go +++ b/cmd/transpile.go @@ -18,9 +18,11 @@ var transpileCmd = &cobra.Command{ Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { result, err := transpiler.GolangToMLOGFile(args[0], transpiler.Options{ - Numbers: viper.GetBool("numbers"), - Comments: viper.GetBool("comments"), - Stacked: viper.GetString("stacked"), + Numbers: viper.GetBool("numbers"), + Comments: viper.GetBool("comments"), + CommentOffset: viper.GetInt("comment-offset"), + Stacked: viper.GetString("stacked"), + Source: viper.GetBool("source"), }) if err != nil { return err diff --git a/m/custom.go b/m/custom.go new file mode 100644 index 0000000..ecf55ed --- /dev/null +++ b/m/custom.go @@ -0,0 +1,36 @@ +package m + +import ( + "github.com/Vilsol/go-mlog/transpiler" + "strings" +) + +func init() { + // TODO Optimize + transpiler.RegisterFuncTranslation("m.Const", 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: "set"}, + vars[0], + &transpiler.Value{Value: strings.Trim(args[0].GetValue(), "\"")}, + }, + }, + }, + }, nil + }, + }) +} + +// Process provided string as a game constant +// +// Example m.Const("@copper") +func Const(constant string) string { + return "" +} diff --git a/transpiler/main.go b/transpiler/main.go index 5810a38..1f4e71d 100644 --- a/transpiler/main.go +++ b/transpiler/main.go @@ -100,11 +100,17 @@ func GolangToMLOG(input string, options Options) (string, error) { prevArgs := 0 for i, param := range castDecl.Type.Params.List { if paramTypeIdent, ok := param.Type.(*ast.Ident); ok { - if paramTypeIdent.Name != "int" && paramTypeIdent.Name != "float64" { - return "", Err(fnCtx, "function parameters may only be integers or floating point numbers") + if options.Stacked != "" { + if paramTypeIdent.Name != "int" && paramTypeIdent.Name != "float64" { + return "", Err(fnCtx, "function parameters may only be integers or floating point numbers in stack mode") + } + } else { + if paramTypeIdent.Name != "int" && paramTypeIdent.Name != "float64" && paramTypeIdent.Name != "string" { + return "", Err(fnCtx, "function parameters may only be integers, floating point numbers or strings") + } } } else { - return "", Err(fnCtx, "function parameters may only be integers or floating point numbers") + return "", Err(fnCtx, "function parameters may only be basic types") } position := len(castDecl.Type.Params.List) - i diff --git a/transpiler/options.go b/transpiler/options.go index 9511cf7..68ebfe4 100644 --- a/transpiler/options.go +++ b/transpiler/options.go @@ -1,8 +1,10 @@ package transpiler type Options struct { - Numbers bool - Comments bool - NoStartup bool - Stacked string + Numbers bool + Comments bool + CommentOffset int + NoStartup bool + Stacked string + Source bool } diff --git a/transpiler/type_base.go b/transpiler/type_base.go index 6a53169..23b908d 100644 --- a/transpiler/type_base.go +++ b/transpiler/type_base.go @@ -3,6 +3,7 @@ package transpiler import ( "context" "go/ast" + "go/token" ) type Global struct { @@ -22,6 +23,8 @@ type Function struct { type MLOGAble interface { ToMLOG() [][]Resolvable GetComment(int) string + SetSourcePos(token.Pos) + GetSourcePos() token.Pos } type Processable interface { diff --git a/transpiler/type_function.go b/transpiler/type_function.go index 5dcc8da..1cfaa91 100644 --- a/transpiler/type_function.go +++ b/transpiler/type_function.go @@ -3,6 +3,7 @@ package transpiler import ( "context" "go/ast" + "go/token" "strconv" ) @@ -13,6 +14,7 @@ type MLOGCustomFunction struct { Unresolved []MLOGStatement FunctionName string Comments map[int]string + SourcePos token.Pos } func (m *MLOGCustomFunction) ToMLOG() [][]Resolvable { @@ -160,3 +162,11 @@ func (m *MLOGCustomFunction) PostProcess(ctx context.Context, global *Global, fu func (m *MLOGCustomFunction) GetComment(pos int) string { return m.Comments[pos] } + +func (m *MLOGCustomFunction) SetSourcePos(pos token.Pos) { + m.SourcePos = pos +} + +func (m *MLOGCustomFunction) GetSourcePos() token.Pos { + return m.SourcePos +} diff --git a/transpiler/type_mlog.go b/transpiler/type_mlog.go index a658029..22e3165 100644 --- a/transpiler/type_mlog.go +++ b/transpiler/type_mlog.go @@ -3,6 +3,7 @@ package transpiler import ( "context" "fmt" + "go/token" "strconv" ) @@ -10,6 +11,7 @@ type MLOG struct { Statement [][]Resolvable Position int Comment string + SourcePos token.Pos } func (m *MLOG) ToMLOG() [][]Resolvable { @@ -59,12 +61,21 @@ func (m *MLOG) GetComment(int) string { return m.Comment } +func (m *MLOG) SetSourcePos(pos token.Pos) { + m.SourcePos = pos +} + +func (m *MLOG) GetSourcePos() token.Pos { + return m.SourcePos +} + type MLOGFunc struct { Position int Function Translator Arguments []Resolvable Variables []Resolvable Unresolved []MLOGStatement + SourcePos token.Pos } func (m *MLOGFunc) ToMLOG() [][]Resolvable { @@ -133,6 +144,14 @@ func (m *MLOGFunc) GetComment(int) string { return "Call to native function" } +func (m *MLOGFunc) SetSourcePos(pos token.Pos) { + m.SourcePos = pos +} + +func (m *MLOGFunc) GetSourcePos() token.Pos { + return m.SourcePos +} + type MLOGTrampoline struct { MLOG Variable string diff --git a/transpiler/type_native.go b/transpiler/type_native.go index 121effb..86a68bb 100644 --- a/transpiler/type_native.go +++ b/transpiler/type_native.go @@ -1,6 +1,9 @@ package transpiler -import "strconv" +import ( + "context" + "strconv" +) type MLOGStackWriter struct { MLOG @@ -30,9 +33,9 @@ type MLOGTrampolineBack struct { Function string } -func (m *MLOGTrampolineBack) ToMLOG() [][]Resolvable { +func (m *MLOGTrampolineBack) PreProcess(ctx context.Context, global *Global, function *Function) error { if m.Stacked != "" { - return [][]Resolvable{ + m.Statement = [][]Resolvable{ { &Value{Value: "read"}, &Value{Value: "@counter"}, @@ -40,15 +43,17 @@ func (m *MLOGTrampolineBack) ToMLOG() [][]Resolvable { &Value{Value: stackVariable}, }, } + } else { + m.Statement = [][]Resolvable{ + { + &Value{Value: "set"}, + &Value{Value: "@counter"}, + &Value{Value: FunctionTrampolinePrefix + m.Function}, + }, + } } - return [][]Resolvable{ - { - &Value{Value: "set"}, - &Value{Value: "@counter"}, - &Value{Value: FunctionTrampolinePrefix + m.Function}, - }, - } + return m.MLOG.PreProcess(ctx, global, function) } func (m *MLOGTrampolineBack) GetComment(int) string { diff --git a/transpiler/types.go b/transpiler/types.go index e13a59a..36648be 100644 --- a/transpiler/types.go +++ b/transpiler/types.go @@ -3,6 +3,7 @@ package transpiler import ( "context" "fmt" + "strconv" ) func MLOGToString(ctx context.Context, statements [][]Resolvable, statement MLOGAble, lineNumber int) string { @@ -21,7 +22,7 @@ func MLOGToString(ctx context.Context, statements [][]Resolvable, statement MLOG } if ctx.Value(contextOptions).(Options).Comments { - result += fmt.Sprintf("%-45s", resultLine) + result += fmt.Sprintf("%-"+strconv.Itoa(ctx.Value(contextOptions).(Options).CommentOffset)+"s", resultLine) result += " // " + statement.GetComment(lineNumber) } else { result += resultLine