Skip to content

Commit ee4bb0c

Browse files
authored
Merge pull request #20 from MinecraftMetascript/0.4.0/polish
0.4.0/polish
2 parents 6ed8787 + 2e5eefd commit ee4bb0c

File tree

9 files changed

+144
-59
lines changed

9 files changed

+144
-59
lines changed

cmd/build.go

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"log"
88
"os"
99
"path"
10-
"strings"
1110

1211
"github.com/minecraftmetascript/mms/lib"
1312
_project "github.com/minecraftmetascript/mms/project"
@@ -72,17 +71,8 @@ var buildCmd = &cobra.Command{
7271
return
7372
}
7473

75-
_, err = fs.Stat(os.DirFS("."), outFile)
76-
if err != nil {
77-
if strings.HasSuffix(err.Error(), "no such file or directory") {
78-
err = os.MkdirAll(outFile, 0755)
79-
if err != nil {
80-
log.Println("Error creating output directory:", err)
81-
return
82-
}
83-
} else {
84-
log.Println("Error building project", err)
85-
}
74+
if err = mkdirIfNotExists(outFile); err != nil {
75+
log.Println("Error creating output directory:", err)
8676
return
8777
}
8878

@@ -105,7 +95,6 @@ var buildCmd = &cobra.Command{
10595
}
10696

10797
func flushProject(root *lib.FileTreeLike, rootPath string) {
108-
log.Println(root.Name)
10998
for _, file := range root.Children {
11099
targetPath := path.Join(rootPath, file.Name)
111100
if file.IsDir {

cmd/lint.go

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package cmd
22

33
import (
4+
"io/fs"
5+
"log"
6+
"os"
7+
"strings"
8+
9+
_project "github.com/minecraftmetascript/mms/project"
410
"github.com/spf13/cobra"
511
)
612

@@ -11,16 +17,42 @@ var lintCmd = &cobra.Command{
1117
Long: ``,
1218
ValidArgs: []cobra.Completion{"Input"},
1319
Run: func(cmd *cobra.Command, args []string) {
14-
//if len(args) < 1 {
15-
// log.Println("Please provide an input file or directory")
16-
// return
17-
//}
18-
//inFile := args[0]
19-
//if strings.HasSuffix(inFile, "/") {
20-
// inFile = strings.TrimSuffix(inFile, "/")
21-
//}
22-
//
23-
//project := lang.NewProject()
20+
if len(args) < 1 {
21+
log.Println("Please provide an input file or directory")
22+
return
23+
}
24+
inFile := args[0]
25+
if strings.HasSuffix(inFile, "/") {
26+
inFile = strings.TrimSuffix(inFile, "/")
27+
}
28+
29+
project := _project.NewProject()
30+
stat, err := fs.Stat(os.DirFS("."), inFile)
31+
32+
if err != nil {
33+
log.Println("Error building project", err)
34+
return
35+
}
36+
37+
if stat.IsDir() {
38+
log.Println("Project is a directory")
39+
} else {
40+
if content, err := os.ReadFile(inFile); err != nil {
41+
log.Println("Error reading project:", err)
42+
} else {
43+
_, err := project.AddFile(inFile, string(content))
44+
45+
if err != nil {
46+
log.Println("Error parsing project:", err)
47+
}
48+
}
49+
}
50+
for _, diag := range project.AllDiagnostics() {
51+
log.Println(diag)
52+
}
53+
54+
project.BuildFsLike(".")
55+
2456
//
2557
//stat, err := fs.Stat(os.DirFS("."), inFile)
2658
//
Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
Namespace mms_demo {
2-
Dimension {
3-
Sunk = DimensionType()
4-
.CoordinateScale(16)
5-
.HasRaids()
6-
.BedsWork()
7-
.PiglinSafe().Infiniburn(#b:la).Height(90)
8-
}
2+
Surface {
3+
InFriendlyBiome = Biome(forest, plains, beach)
4+
InUnfriendlyBiome = Biome(desert, badlands, deep_ocean)
95

6+
HoneySurface = Block(honey)
7+
SlimeSurface = Block(slime)
108

11-
Surface {
12-
A = NoiseThreshold(Noise(-5)).Min(5).Max(2)
13-
}
14-
}
9+
MyStrangeSurface = [
10+
If (mms_demo:InFriendlyBiome) HoneySurface
11+
If (mms_demo:InUnfriendlyBiome) SlimeSurface
12+
Block(magma_block)
13+
]
14+
}
15+
}

lang/Dimensions.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,30 @@ import (
1111
"github.com/minecraftmetascript/mms/lib"
1212
)
1313

14+
func exporter[T any](serializer func(node T) any, rootPath []string, extension string) func(fn T, name string) *lib.FileTreeLike {
15+
return func(fn T, name string) *lib.FileTreeLike {
16+
content := serializer(fn)
17+
contentBytes, err := json.MarshalIndent(content, "", " ")
18+
if err != nil {
19+
log.Println("Error marshalling: ", err)
20+
return nil
21+
}
22+
23+
if len(rootPath) == 0 {
24+
log.Println("exporter requires at least one path segment")
25+
return nil
26+
}
27+
root := lib.NewDirLike(rootPath[0], nil)
28+
current := root
29+
for _, part := range rootPath[1:] {
30+
current = current.MkDir(part, nil)
31+
}
32+
current.MkFile(fmt.Sprintf("%s.%s", name, extension), string(contentBytes), nil)
33+
34+
return root
35+
}
36+
}
37+
1438
func exportWorldgen(serializer func(node spec.FunctionNode) any, subdir string) func(fn spec.FunctionNode, name string) *lib.FileTreeLike {
1539
return func(fn spec.FunctionNode, name string) *lib.FileTreeLike {
1640
content := serializer(fn)

lang/Registries.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
11
package lang
22

33
import (
4+
"github.com/minecraftmetascript/mms/lang/ast"
45
"github.com/minecraftmetascript/mms/lang/spec"
6+
"github.com/minecraftmetascript/mms/lib"
57
)
68

79
var Blocks = spec.NewBlockSpecList()
10+
11+
// JitSymbols is a map of all the symbols present in a project that will be populated immediately prior to serialization
12+
var JitSymbols = map[string]*ast.Namespace{}
13+
14+
func getSymbol(namespace, name string) ast.Symbol {
15+
if symbolNs, ok := JitSymbols[namespace]; ok {
16+
return symbolNs.GetDecl(name)
17+
}
18+
return nil
19+
}
20+
21+
func getSymbolValue(namespace, name string) any {
22+
if symbol := getSymbol(namespace, name); !lib.IsNilInterface(symbol) {
23+
return symbol.ToSerializable()
24+
}
25+
return nil
26+
}

lang/SurfaceRules.go

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -350,50 +350,59 @@ func YAboveSerializer(node spec.FunctionNode) any {
350350
return out
351351
}
352352

353+
func serializeListSurfaceRule(node spec.ListNode) any {
354+
out := struct {
355+
Type string `json:"type"`
356+
Sequence []any `json:"sequence"`
357+
}{
358+
Type: "minecraft:sequence",
359+
Sequence: make([]any, 0),
360+
}
361+
362+
for _, val := range node.Values {
363+
if s, ok := val.(ast.Symbol); ok && !lib.IsNilInterface(s) {
364+
out.Sequence = append(out.Sequence, s.ToSerializable())
365+
}
366+
}
367+
368+
return out
369+
}
370+
371+
var SurfaceConditionRef = spec.NewReferenceSpec(ast.SymbolSurfaceCondition)
372+
var SurfaceRuleRef = spec.NewReferenceSpec(ast.SymbolSurfaceRule)
373+
353374
func init() {
354375
Conditional = spec.NewConditionSpec().
355376
SetKind(ast.SymbolSurfaceRule).
356377
SetHelp("Applies a rule based on a surface condition")
357378
SurfaceConditions.Add(AboveSurface, Biome, Hole, NoiseThreshold, Steep, StoneDepth, Frozen, Water, VerticalGradient, YAbove)
358379
SurfaceRules.Add(Bandlands, Block, Conditional)
359380
ListRule := spec.NewListSpec().
360-
SetOutputFn(
361-
func(node spec.ListNode) any {
362-
out := struct {
363-
Type string `json:"type"`
364-
Sequence []any `json:"sequence"`
365-
}{
366-
Type: "minecraft:sequence",
367-
Sequence: make([]any, 0),
368-
}
369-
370-
for _, val := range node.Values {
371-
if s, ok := val.(ast.Symbol); ok && !lib.IsNilInterface(s) {
372-
out.Sequence = append(out.Sequence, s.ToSerializable())
373-
}
374-
}
375-
376-
return out
377-
}).
381+
SetOutputFn(serializeListSurfaceRule).
382+
SetFileExporter(exporter(serializeListSurfaceRule, []string{"worldgen", "debug", "surface"}, "json")).
378383
SetKind(ast.SymbolSurfaceRule).
379384
SetHelp("Creates a list of rules, the first valid rule will be used.s")
380385
SurfaceRules.Add(ListRule)
381386

382387
Conditional.
383388
AddConditionOption(SurfaceConditions).
384-
AddConditionOption(spec.NewReferenceSpec(ast.SymbolSurfaceCondition)).
389+
AddConditionOption(SurfaceConditionRef).
385390
AddValueOption(SurfaceRules).
386-
AddValueOption(spec.NewReferenceSpec(ast.SymbolSurfaceRule)).
391+
AddValueOption(SurfaceRuleRef).
387392
SetOutputFn(func(n spec.ConditionalNode) any {
388393
var val any = nil
389-
if n.Value != nil && n.Value.ToSerializable() != nil {
390-
val = n.Value.ToSerializable()
394+
if !lib.IsNilInterface(n.Value) {
395+
if ref, ok := n.Value.(*spec.ReferenceNode); ok {
396+
val = getSymbolValue(ref.Namespace, ref.Name)
397+
} else if !lib.IsNilInterface(n.Value.ToSerializable()) {
398+
val = n.Value.ToSerializable()
399+
}
391400
}
392401
return SerializeConditional(n.Condition, val)
393402
})
394403

395404
ListRule.
396-
AddValueOption(spec.NewReferenceSpec(ast.SymbolSurfaceRule)).
405+
AddValueOption(SurfaceRuleRef).
397406
AddValueOption(SurfaceRules)
398407

399408
SurfaceRuleBlock = spec.NewBlockSpec(
@@ -490,6 +499,12 @@ func SerializeConditional(cond ast.Symbol, value any) any {
490499
// There is no condition yet
491500
return mkSurfaceRuleConditional(nil, value)
492501
default:
502+
if ref, ok := c.(*spec.ReferenceNode); ok {
503+
val := getSymbolValue(ref.Namespace, ref.Name)
504+
if val != nil {
505+
return mkSurfaceRuleConditional(val, value)
506+
}
507+
}
493508
// Atomic condition: single condition node
494509
return mkSurfaceRuleConditional(c.ToSerializable(), value)
495510
}

lang/spec/List.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ type ListSpec struct {
2222
}
2323

2424
func (l *ListSpec) UsageStr() string {
25-
2625
validOptions := lo.Filter(l.ValueOptions, func(item ValueSpec, index int) bool {
2726
return !lib.IsNilInterface(item) && item != l
2827
})

lang/spec/Reference.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ type ReferenceNode struct {
146146
Kind ast.SymbolKind
147147
}
148148

149+
func (r *ReferenceNode) ToSerializable() any {
150+
return r.Ref()
151+
}
152+
149153
func (r *ReferenceNode) Ref() string {
150154
return fmt.Sprintf("%s:%s", r.Namespace, r.Name)
151155
}

project/Project.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package project
33
import (
44
"slices"
55

6+
"github.com/minecraftmetascript/mms/lang"
67
"github.com/minecraftmetascript/mms/lang/ast"
78
"github.com/minecraftmetascript/mms/lib"
89
"github.com/samber/lo"
@@ -59,9 +60,10 @@ func (p *Project) AddFile(path, content string) (*File, error) {
5960
func (p *Project) BuildFsLike(root string) *lib.FileTreeLike {
6061
rootDir := lib.NewDirLike(root, nil)
6162

63+
lang.JitSymbols = p.Symbols()
64+
6265
for ns, decls := range p.symbols {
6366
nsDir := rootDir.MkDir(ns, nil)
64-
6567
for name, decl := range decls.AllDecls() {
6668
declFs := decl.ToFileTreeLike(name)
6769
if declFs != nil {

0 commit comments

Comments
 (0)