-
Notifications
You must be signed in to change notification settings - Fork 0
/
homescript.go
68 lines (60 loc) · 2.14 KB
/
homescript.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package homescript
import (
"context"
"fmt"
"github.com/smarthome-go/homescript/v3/homescript/analyzer"
"github.com/smarthome-go/homescript/v3/homescript/analyzer/ast"
"github.com/smarthome-go/homescript/v3/homescript/diagnostic"
"github.com/smarthome-go/homescript/v3/homescript/errors"
"github.com/smarthome-go/homescript/v3/homescript/interpreter"
"github.com/smarthome-go/homescript/v3/homescript/interpreter/value"
"github.com/smarthome-go/homescript/v3/homescript/parser"
pAst "github.com/smarthome-go/homescript/v3/homescript/parser/ast"
)
func Parse(code string, filename string) (pAst.Program, []errors.Error, *errors.Error) {
lexer := parser.NewLexer(code, filename)
parser := parser.NewParser(lexer, filename)
return parser.Parse()
}
type InputProgram struct {
ProgramText string
Filename string
}
func Analyze(
input InputProgram,
scopeAdditions map[string]analyzer.Variable,
host analyzer.HostDependencies,
) (modules map[string]ast.AnalyzedProgram, diagnostics []diagnostic.Diagnostic, syntaxErrors []errors.Error) {
lexer := parser.NewLexer(input.ProgramText, input.Filename)
parser := parser.NewParser(lexer, input.Filename)
parsedTree, nonCriticalErrors, criticalError := parser.Parse()
syntaxErrors = append(syntaxErrors, nonCriticalErrors...)
if criticalError != nil {
syntaxErrors = append(syntaxErrors, *criticalError)
return nil, nil, syntaxErrors
}
analyzer := analyzer.NewAnalyzer(host, scopeAdditions)
analyzedModules, diagnostics, analyzedSyntaxErrors := analyzer.Analyze(parsedTree)
syntaxErrors = append(syntaxErrors, analyzedSyntaxErrors...)
return analyzedModules, diagnostics, syntaxErrors
}
func Run(
callStackLimitSize uint,
inputModules map[string]ast.AnalyzedProgram,
entryModule string,
executor value.Executor,
scopeAdditions map[string]value.Value,
cancelCtx *context.Context,
) *value.Interrupt {
interpreter := interpreter.NewInterpreter(
callStackLimitSize,
executor,
inputModules,
scopeAdditions,
cancelCtx,
)
if _, found := inputModules[entryModule]; !found {
panic(fmt.Sprintf("Entry module `%s` is not among input modules", entryModule))
}
return interpreter.Execute(entryModule)
}