sema

package
v0.0.0-...-90e8e0c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2024 License: MIT Imports: 10 Imported by: 0

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

View Source
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 Label struct {
	ast.Stmt // StmtLabel or StmtLabelCallable
	// contains filtered or unexported fields
}

func (Label) Name

func (l Label) Name() string

type MemAccess

type MemAccess uint8
const (
	Unknown MemAccess = iota
	Load
	Store
)

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
}

func (*Sema) Analyze

func (sema *Sema) Analyze(entry string) error

func (*Sema) Init

func (sema *Sema) Init(
	options Options,
	builtins *Package,
	globals []ast.StmtGlobal,
	stmts []ast.Stmt,
	imports map[string]*Package,
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL