Skip to content

Commit

Permalink
declare base values and base types in activations, reuse them when co…
Browse files Browse the repository at this point in the history
…nstruction new checkers
  • Loading branch information
turbolent committed Mar 3, 2021
1 parent c2488fd commit f3be170
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 150 deletions.
2 changes: 1 addition & 1 deletion runtime/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3427,7 +3427,7 @@ func (interpreter *Interpreter) importResolvedLocation(resolvedLocation sema.Res
}

// don't import base values
if _, ok := sema.BaseValues.Get(name); ok {
if sema.BaseValueActivation.Find(name) != nil {
continue
}

Expand Down
58 changes: 0 additions & 58 deletions runtime/sema/basefunction.go

This file was deleted.

31 changes: 3 additions & 28 deletions runtime/sema/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,30 +220,18 @@ func NewChecker(program *ast.Program, location common.Location, options ...Optio
return nil, &MissingLocationError{}
}

valueActivations := NewValueActivations(BaseValueActivation)
typeActivations := NewValueActivations(BaseTypeActivation)
functionActivations := &FunctionActivations{}
functionActivations.EnterFunction(&FunctionType{
ReturnTypeAnnotation: NewTypeAnnotation(VoidType)},
0,
)

typeActivations := NewValueActivations()
baseTypes.Foreach(func(name string, baseType Type) {
_, err := typeActivations.DeclareType(typeDeclaration{
identifier: ast.Identifier{Identifier: name},
ty: baseType,
declarationKind: common.DeclarationKindType,
access: ast.AccessPublic,
allowOuterScopeShadowing: false,
})
if err != nil {
panic(err)
}
})

checker := &Checker{
Program: program,
Location: location,
valueActivations: NewValueActivations(),
valueActivations: valueActivations,
resources: NewResources(),
typeActivations: typeActivations,
functionActivations: functionActivations,
Expand All @@ -253,8 +241,6 @@ func NewChecker(program *ast.Program, location common.Location, options ...Optio

checker.beforeExtractor = NewBeforeExtractor(checker.report)

checker.declareBaseValues()

for _, option := range options {
err := option(checker)
if err != nil {
Expand Down Expand Up @@ -284,17 +270,6 @@ func (checker *Checker) SubChecker(program *ast.Program, location common.Locatio
)
}

func (checker *Checker) declareBaseValues() {
BaseValues.Foreach(func(_ string, declaration ValueDeclaration) {
variable := checker.declareValue(declaration)
if variable == nil {
return
}
variable.IsBaseValue = true
checker.Elaboration.GlobalValues.Set(variable.Identifier, variable)
})
}

func (checker *Checker) declareValue(declaration ValueDeclaration) *Variable {

if !declaration.ValueDeclarationAvailable(checker.Location) {
Expand Down
4 changes: 2 additions & 2 deletions runtime/sema/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (i ElaborationImport) AllValueElements() *StringImportElementOrderedMap {
}

func (i ElaborationImport) IsImportableValue(name string) bool {
if _, ok := BaseValues.Get(name); ok {
if BaseValueActivation.Find(name) != nil {
return false
}

Expand All @@ -83,7 +83,7 @@ func (i ElaborationImport) AllTypeElements() *StringImportElementOrderedMap {
}

func (i ElaborationImport) IsImportableType(name string) bool {
if _, ok := baseTypes.Get(name); ok {
if BaseTypeActivation.Find(name) != nil {
return false
}

Expand Down
160 changes: 102 additions & 58 deletions runtime/sema/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"sync"

"github.com/onflow/cadence/fixedpoint"
"github.com/onflow/cadence/runtime/activations"
"github.com/onflow/cadence/runtime/ast"
"github.com/onflow/cadence/runtime/common"
"github.com/onflow/cadence/runtime/errors"
Expand Down Expand Up @@ -3844,15 +3845,13 @@ func (t *CheckedFunctionType) CheckArgumentExpressions(
t.ArgumentExpressionsCheck(checker, argumentExpressions, invocationRange)
}

// baseTypes are the nominal types available in programs
// BaseTypeActivation is the base activation that contains
// the types available in programs
//
var baseTypes = NewStringTypeOrderedMap()
var BaseTypeActivation = activations.NewActivation(nil)

func init() {

baseTypes = NewStringTypeOrderedMap()
baseTypes.Set("", VoidType)

otherTypes := []Type{
MetaType,
VoidType,
Expand Down Expand Up @@ -3883,18 +3882,41 @@ func init() {
for _, ty := range types {
typeName := ty.String()

// check type is not accidentally redeclared
if _, ok := baseTypes.Get(typeName); ok {
// Check that the type is not accidentally redeclared

if BaseTypeActivation.Find(typeName) != nil {
panic(errors.NewUnreachableError())
}

baseTypes.Set(typeName, ty)
BaseTypeActivation.Set(
typeName,
baseTypeVariable(typeName, ty),
)
}

// The AST contains empty type annotations, resolve them to Void

BaseTypeActivation.Set(
"",
BaseTypeActivation.Find("Void"),
)
}

// BaseValues are the values available in programs
func baseTypeVariable(name string, ty Type) *Variable {
return &Variable{
Identifier: name,
Type: ty,
DeclarationKind: common.DeclarationKindType,
IsConstant: true,
IsBaseValue: true,
Access: ast.AccessPublic,
}
}

// BaseValueActivation is the base activation that contains
// the values available in programs
//
var BaseValues = NewStringValueDeclarationOrderedMap()
var BaseValueActivation = activations.NewActivation(nil)

var AllSignedFixedPointTypes = []Type{
&Fix64Type{},
Expand Down Expand Up @@ -3972,71 +3994,89 @@ func init() {
default:
typeName := numberType.String()

// Check that the type is not accidentally redeclared
// Check that the function is not accidentally redeclared

if _, ok := BaseValues.Get(typeName); ok {
if BaseValueActivation.Find(typeName) != nil {
panic(errors.NewUnreachableError())
}

BaseValues.Set(typeName, baseFunction{
name: typeName,
invokableType: &CheckedFunctionType{
FunctionType: &FunctionType{
Parameters: []*Parameter{
{
Label: ArgumentLabelNotRequired,
Identifier: "value",
TypeAnnotation: NewTypeAnnotation(&NumberType{}),
BaseValueActivation.Set(
typeName,
baseFunctionVariable(
typeName,
&CheckedFunctionType{
FunctionType: &FunctionType{
Parameters: []*Parameter{
{
Label: ArgumentLabelNotRequired,
Identifier: "value",
TypeAnnotation: NewTypeAnnotation(&NumberType{}),
},
},
ReturnTypeAnnotation: NewTypeAnnotation(numberType),
},
ReturnTypeAnnotation: NewTypeAnnotation(numberType),
ArgumentExpressionsCheck: numberFunctionArgumentExpressionsChecker(numberType),
},
ArgumentExpressionsCheck: numberFunctionArgumentExpressionsChecker(numberType),
},
})
),
)
}
}
}

func baseFunctionVariable(name string, ty InvokableType) *Variable {
return &Variable{
Identifier: name,
DeclarationKind: common.DeclarationKindFunction,
IsConstant: true,
IsBaseValue: true,
Type: ty,
Access: ast.AccessPublic,
}
}

func init() {

// Declare a conversion function for the address type

addressType := &AddressType{}
typeName := addressType.String()

// check type is not accidentally redeclared
if _, ok := BaseValues.Get(typeName); ok {
// Check that the function is not accidentally redeclared

if BaseValueActivation.Find(typeName) != nil {
panic(errors.NewUnreachableError())
}

BaseValues.Set(typeName, baseFunction{
name: typeName,
invokableType: &CheckedFunctionType{
FunctionType: &FunctionType{
Parameters: []*Parameter{
{
Label: ArgumentLabelNotRequired,
Identifier: "value",
TypeAnnotation: NewTypeAnnotation(&IntegerType{}),
BaseValueActivation.Set(
typeName,
baseFunctionVariable(
typeName,
&CheckedFunctionType{
FunctionType: &FunctionType{
Parameters: []*Parameter{
{
Label: ArgumentLabelNotRequired,
Identifier: "value",
TypeAnnotation: NewTypeAnnotation(&IntegerType{}),
},
},
ReturnTypeAnnotation: NewTypeAnnotation(addressType),
},
ReturnTypeAnnotation: NewTypeAnnotation(addressType),
},
ArgumentExpressionsCheck: func(checker *Checker, argumentExpressions []ast.Expression, _ ast.Range) {
if len(argumentExpressions) < 1 {
return
}
ArgumentExpressionsCheck: func(checker *Checker, argumentExpressions []ast.Expression, _ ast.Range) {
if len(argumentExpressions) < 1 {
return
}

intExpression, ok := argumentExpressions[0].(*ast.IntegerExpression)
if !ok {
return
}
intExpression, ok := argumentExpressions[0].(*ast.IntegerExpression)
if !ok {
return
}

CheckAddressLiteral(intExpression, checker.report)
CheckAddressLiteral(intExpression, checker.report)
},
},
},
})
),
)
}

func numberFunctionArgumentExpressionsChecker(targetType Type) ArgumentExpressionsCheck {
Expand Down Expand Up @@ -4177,18 +4217,22 @@ func init() {

typeName := MetaType.String()

// check type is not accidentally redeclared
if _, ok := BaseValues.Get(typeName); ok {
// Check that the function is not accidentally redeclared

if BaseValueActivation.Find(typeName) != nil {
panic(errors.NewUnreachableError())
}

BaseValues.Set(typeName, baseFunction{
name: typeName,
invokableType: &FunctionType{
TypeParameters: []*TypeParameter{{Name: "T"}},
ReturnTypeAnnotation: NewTypeAnnotation(MetaType),
},
})
BaseValueActivation.Set(
typeName,
baseFunctionVariable(
typeName,
&FunctionType{
TypeParameters: []*TypeParameter{{Name: "T"}},
ReturnTypeAnnotation: NewTypeAnnotation(MetaType),
},
),
)
}

// CompositeType
Expand Down
Loading

0 comments on commit f3be170

Please sign in to comment.