Documentation
¶
Overview ¶
Package sema provides semantic analysis of statements and ensures that the code is safe as far as the language semantics permit.
It checks that: - labels and globals are unique and dont clash - the entry label cannot be called - non callable labels must be hit at least once - goto and call statements points to an existing label - goto statements cannot refer to labels outside of their callable label - call statements reference a callable label (with ->) - called labels contain a return or exit statement in their top scope - called labels cannot be nested - test tag on labels can only be used in .klt files - switch cases have unique values and no more than one default - switch case values are constant - if defined, the switch default must be the last case and be unique - a switch statement must contain at least one non default case - check globals being assigned to exist - array references do exist (no out of bounds access) - assignment to global array is invalid, must select index - validate types when assigning to an array - check that builtins are available for a given os/architecture - check that the .size operator is applied to an array or string - push/pop instructions must have at least one argument - for loops composites do exist - ensure embedded files do exist and are readable - resolve ValueLen and ValueSize.Size - shift left and right operands must be unsigned - .len of an array value must be a string - condition's operands have the same type - constant globals are not written to - references to imports do exist (labels and globals) - exported labels must be callable (disallow goto statements to packages' labels) - code without a label after a goto is unreachable - no unused imports (need to call the CheckImports() method) - min and max operands must be one of ValueVar, ValueUnsigned, ValueSigned, ValueString - min and max operands must have at least one ValueVar - ensure push/pops are balanced within a scope - division dividend must be one of ValueUnsigned, ValueSigned or ValueVar - ValueSigned type must be signed
It adds the following safety checks: - division by zero when the divisor is runtime known - out of bound access when the index is runtime knownn
It transforms the statements the following situations: - assign zero - assert, if, while conditions always true/false - mul, div, mod by 1 - add, sub by 0 - remove empty statements in switch cases with no default - evaluate static switches - expand StmtBuiltin{Assert, Exit, Panic, Print, Syscall}
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrArrayAccessOOB = errors.New("array access out of bound") ErrArrayAssign = errors.New("cannot assign to global array") ErrCompositeRequired = errors.New("need an array, string or a global") ErrCompositeGlobalRequired = errors.New("need an array or string") ErrCannotEmbedDir = errors.New("cannot embed directory") ErrDuplicateGlobal = errors.New("duplicate global") ErrDuplicateLabel = errors.New("duplicate label") ErrDuplicateValue = errors.New("duplicate value") ErrDuplicatefault = errors.New("duplicate default") ErrEntryNotCallable = errors.New("entry label is not callable") ErrGlobalConstantMutation = errors.New("cannot modify constant") ErrGlobalNotArray = errors.New("cannot index a non array global") ErrGotoOutsideScope = errors.New("goto outside of callable scope") ErrTooManyPops = errors.New("too many pops") ErrTooManyPushes = errors.New("too many pushes") ErrIncompatibleType = errors.New("incompatible type") ErrIndexedLenNotString = errors.New("indexed value length must be a string") ErrInvalidArrayAssign = errors.New("cannot assign an array") ErrInvalidDividend = errors.New("dividend must an integer or variable") ErrInvalidLabelTestTag = errors.New(fmt.Sprintf("test labels must be in %s files", ast.TestExt)) ErrInvalidNestedCall = errors.New("cannot nest callable labels") ErrInvalidShiftOperand = errors.New("shift operand must be unsigned") ErrInvalidSize = errors.New("size can only be applied to array and string") ErrInvalidSwitchcase = errors.New("switch case must have at least one non default case") ErrInvalidSwitchcaseValue = errors.New("switch case must be constant") ErrInvalidSwitchcaseDefault = errors.New("default switch case must be defined last") ErrTooManySwitchcaseDefault = errors.New("default switch case must be defined once") ErrLabelGlobal = errors.New("label cannot match global name") ErrMissingCallReturn = errors.New("missing return, exit or panic for call") ErrMissingEntry = errors.New("missing entry") ErrMissingGlobal = errors.New("missing global") ErrMissingImport = errors.New("missing import") ErrMissingImportSymbol = errors.New("missing import symbol") ErrMissingLabel = errors.New("missing label") ErrMissingVar = errors.New("missing variable") ErrNonScalar = errors.New("non scalar value") ErrStringRequired = errors.New("need a string") ErrTypeMismatch = errors.New("type mismatch") ErrUncallableLabel = errors.New("uncallable label") ErrUnreachableCode = errors.New("unreachable code") ErrUnusedImport = errors.New("unused import") ErrUnusedLabel = errors.New("unused label") )
Functions ¶
This section is empty.
Types ¶
type Label ¶
type Options ¶
type Options struct {
// Files contains the source files sorted by name.
Files []string
Platform platform.Platform
// TestingPkg indicates whether the package being processing is a testing one.
TestingPkg bool
// ArrayBoundSafety inserts a check on every array access done via a variable.
ArrayBoundSafety bool
// DivByZeroSafety inserts a check on every division done via a variable.
DivByZeroSafety bool
}
type Package ¶
type Package struct {
// Location in the PackageFile.
ast.Location
// Name uniquely identifies this Package (from kl.pkg import).
Name string
// Sema is the processed source files for this package.
Sema *Sema
// BuildArtifact is set by the backend's that generated this package.
BuildArtifact string
}
type Sema ¶
type Sema struct {
Options Options
IsBuiltin bool
Globals []ast.StmtGlobal
Statements []ast.Stmt
// Interned strings.
// Each string gets assigned a unique id.
Strings map[string]int
// Imports defined for this Sema.
Imports map[string]*Package
// Externals is the set of all external symbols referenced by this Sema.
Externals map[ast.Symbol]struct{}
// PublicSymbols are this Sema's exported symbols sorted in ascending order.
PublicSymbols []string
// Map a symbol to its Global.
// NB. symbols **must** have their location cleared.
// NB. The pointer means that Globals must not be mutated after Init().
GlobalsMap map[ast.Symbol]*ast.StmtGlobal
// contains filtered or unexported fields
}