tala-core-0.1.0: src/Progmasoft/Tala/Desugarer/Symbols.hs
-- SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com>
-- SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-1.1
{- | Tables the lowering to Core reads and does not change: the symbols a
typed tree already uses, and the Core primitive each source operator stands
for.
-}
module Progmasoft.Tala.Desugarer.Symbols
( syntaxSymbolIds
, lowerUnary
, lowerBinary
) where
import Progmasoft.Tala.AST
import Progmasoft.Tala.Core
{- | Every symbol a typed tree declares or binds.
Generated Core bindings must never collide with source symbols. Gathering
the complete typed tree once is cheaper and more robust than reserving a
magic numeric range or deriving identities from source positions.
-}
syntaxSymbolIds :: SyntaxTree ResolvedName Type -> [Int]
syntaxSymbolIds (SyntaxTree _ declarations) = concatMap declarationSymbolIds declarations
declarationSymbolIds :: Declaration ResolvedName Type -> [Int]
declarationSymbolIds declaration =
symbolValue (declarationName declaration)
: case declaration of
TypeDeclaration {typeMembers = members} -> concatMap declarationSymbolIds members
TemplateTypeDeclaration {declarationTemplateParameters = parameters, typeMembers = members} ->
map (symbolValue . templateParameterName) parameters ++ concatMap declarationSymbolIds members
FunctionDeclaration {declarationParameters = parameters, declarationBody = body} ->
map (symbolValue . parameterName) parameters ++ blockSymbolIds body
EnumDeclaration {} -> []
blockSymbolIds :: Block ResolvedName Type -> [Int]
blockSymbolIds (Block statements) = concatMap statementIds statements
statementIds :: Statement ResolvedName Type -> [Int]
statementIds statement = case statement of
BindingStatement _ _ _ name _ value -> symbolValue name : expressionIds value
AssignmentStatement _ name _ value -> symbolValue name : expressionIds value
ReturnStatement _ value -> maybe [] expressionIds value
IfStatement _ condition yes no -> expressionIds condition ++ blockSymbolIds yes ++ maybe [] blockSymbolIds no
WhileStatement _ condition body -> expressionIds condition ++ blockSymbolIds body
DoWhileStatement _ body condition -> blockSymbolIds body ++ expressionIds condition
ForStatement _ initializer condition updates body ->
maybe [] statementIds initializer
++ maybe [] expressionIds condition
++ concatMap statementIds updates
++ blockSymbolIds body
ForEachStatement _ _ _ name _ source body ->
symbolValue name : expressionIds source ++ blockSymbolIds body
IncrementStatement _ name _ -> [symbolValue name]
CompoundAssignmentStatement _ _ name _ value -> symbolValue name : expressionIds value
DiscardStatement _ value -> expressionIds value
BreakStatement _ value -> maybe [] expressionIds value
ContinueStatement {} -> []
GuardStatement _ condition block -> expressionIds condition ++ blockSymbolIds block
BlockStatement _ block -> blockSymbolIds block
ExpressionStatement _ value _ -> expressionIds value
expressionIds :: Expression ResolvedName Type -> [Int]
expressionIds expression = case expression of
NameExpression _ name _ -> [symbolValue name]
LiteralExpression {} -> []
MemberAccessExpression _ receiver _ _ -> expressionIds receiver
MethodReferenceExpression _ receiver _ _ -> expressionIds receiver
CallExpression _ callee arguments _ -> expressionIds callee ++ concatMap expressionIds arguments
UnaryExpression _ _ value _ -> expressionIds value
BinaryExpression _ _ left right _ -> expressionIds left ++ expressionIds right
IsPatternExpression _ subject _ _ -> expressionIds subject
ConditionalExpression _ condition first second _ -> concatMap expressionIds [condition, first, second]
CoalesceExpression _ left fallback _ -> expressionIds left ++ expressionIds fallback
AssignmentExpression _ _ name value _ -> symbolValue name : expressionIds value
IncrementExpression _ _ name _ -> [symbolValue name]
LoopExpression _ loop _ -> statementIds loop
BlockExpression _ block _ -> blockSymbolIds block
MatchExpression _ subjects arms _ ->
[ symbolValue name
| arm <- arms
, Just name <- map matchPatternBinding (matchArmPatterns arm)
]
++ concatMap expressionIds (subjects ++ concatMap matchArmExpressions arms)
CallableExpression _ _ captures parameters body _ ->
map (symbolValue . captureName) captures
++ concatMap (maybe [] expressionIds . captureInitializer) captures
++ map (symbolValue . parameterName) parameters
++ callableBodyIds body
callableBodyIds :: CallableBody ResolvedName Type -> [Int]
callableBodyIds body = case body of
CallableExpressionBody expression -> expressionIds expression
CallableBlockBody block -> blockSymbolIds block
symbolValue :: ResolvedName -> Int
symbolValue = symbolIdValue . resolvedSymbol
-- | The Core primitive of a unary operator.
lowerUnary :: UnaryOperator -> CorePrimitive
lowerUnary UnaryNegate = CoreNegate
lowerUnary LogicalNot = CoreLogicalNot
lowerUnary BitwiseNot = CoreBitwiseNot
lowerUnary UnaryPlus = CoreAdd
-- | The Core primitive of a binary operator.
lowerBinary :: BinaryOperator -> CorePrimitive
lowerBinary operator = case operator of
Add -> CoreAdd
Subtract -> CoreSubtract
Multiply -> CoreMultiply
Divide -> CoreDivide
FloorDivide -> CoreFloorDivide
Remainder -> CoreRemainder
Power -> CorePower
ShiftLeft -> CoreShiftLeft
ShiftRight -> CoreShiftRight
BitwiseAnd -> CoreBitwiseAnd
BitwiseXor -> CoreBitwiseXor
BitwiseOr -> CoreBitwiseOr
LessThan -> CoreLessThan
LessEqual -> CoreLessEqual
GreaterThan -> CoreGreaterThan
GreaterEqual -> CoreGreaterEqual
Equal -> CoreEqual
NotEqual -> CoreNotEqual
LogicalAnd -> CoreLogicalAnd
LogicalOr -> CoreLogicalOr