Skip to content

Commit

Permalink
Update all ExprKinds to wrap structs (#356)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinbarabash committed Aug 25, 2024
1 parent 685f22a commit b277f53
Show file tree
Hide file tree
Showing 57 changed files with 1,695 additions and 1,412 deletions.
72 changes: 42 additions & 30 deletions src/Escalier.Codegen/Codegen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ module rec Codegen =
|> Set.toList
|> List.map (fun localName ->
let importName =
if localName.[0] = '_' then localName.[1..] else localName
if localName[0] = '_' then localName[1..] else localName

TS.ImportSpecifier.Named
{ Local = { Name = localName; Loc = None }
Expand Down Expand Up @@ -100,13 +100,17 @@ module rec Codegen =

let flattenLogicalOr (expr: Expr) : list<Expr> =
match expr.Kind with
| ExprKind.Binary("||", left, right) ->
| ExprKind.Binary { Op = "||"
Left = left
Right = right } ->
flattenLogicalOr left @ flattenLogicalOr right
| _ -> [ expr ]

let flattenLogicalAnd (expr: Expr) : list<Expr> =
match expr.Kind with
| ExprKind.Binary("&&", left, right) ->
| ExprKind.Binary { Op = "&&"
Left = left
Right = right } ->
flattenLogicalAnd left @ flattenLogicalAnd right
| _ -> [ expr ]

Expand Down Expand Up @@ -288,7 +292,8 @@ module rec Codegen =
Loc = None }

(callExpr, calleeStmts @ (argStmts |> List.concat))
| ExprKind.Identifier name -> Expr.Ident { Name = name; Loc = None }, []
| ExprKind.Identifier { Name = name } ->
Expr.Ident { Name = name; Loc = None }, []
| ExprKind.Literal lit ->
let lit =
match lit with
Expand All @@ -302,7 +307,7 @@ module rec Codegen =
{ Ident.Name = "undefined"; Loc = None } |> Expr.Ident

lit, []
| ExprKind.Binary(op, left, right) ->
| ExprKind.Binary { Op = op; Left = left; Right = right } ->
if op = "&&" then
buildLogicalRec ctx Logical.And (flattenLogicalAnd expr)
elif op = "||" then
Expand Down Expand Up @@ -388,7 +393,9 @@ module rec Codegen =
let expr = Expr.Arrow { Params = ps; Body = body }

(expr, [])
| ExprKind.IfElse(condition, thenBranch, elseBranch) ->
| ExprKind.IfElse { Condition = condition
Then = thenBranch
Else = elseBranch } ->
let tempId = ctx.GetTempId()
let finalizer = Finalizer.Assign tempId
let tempDecl = buildTempDecl ctx tempId
Expand Down Expand Up @@ -418,7 +425,9 @@ module rec Codegen =
let expr = Expr.Ident { Name = tempId; Loc = None }

(expr, stmts)
| ExprKind.Member(target, name, opt_chain) ->
| ExprKind.Member { Target = target
Name = name
OptChain = opt_chain } ->

// TODO: support outputting optional chaining
let object, objStmts = buildExpr ctx target
Expand All @@ -444,7 +453,7 @@ module rec Codegen =
|> List.map (fun elem ->
match elem with
| ObjElem.Property(span, name, value) ->
let (value, valueStmts) = buildExpr ctx value
let value, valueStmts = buildExpr ctx value
stmts <- stmts @ valueStmts

let key =
Expand Down Expand Up @@ -490,7 +499,7 @@ module rec Codegen =
Expr.Object obj

(expr, [])
| ExprKind.ExprWithTypeArgs(target, typeArgs) ->
| ExprKind.ExprWithTypeArgs { Expr = target; TypeArgs = typeArgs } ->
failwith "TODO: buildExpr - ExprWithTypeArgs"
| ExprKind.Class ``class`` -> failwith "TODO: buildExpr - Class"
| ExprKind.Tuple { Elems = elems; Immutable = immutable } ->
Expand Down Expand Up @@ -518,7 +527,9 @@ module rec Codegen =

(tuple, stmts)
| ExprKind.Range range -> failwith "TODO: buildExpr - Range"
| ExprKind.Index(target, index, optChain) ->
| ExprKind.Index { Target = target
Index = index
OptChain = optChain } ->
let targetExpr, targetStmts = buildExpr ctx target
let indexExpr, indexStmts = buildExpr ctx index

Expand All @@ -531,7 +542,10 @@ module rec Codegen =
Loc = None }

(expr, targetStmts @ indexStmts)
| ExprKind.IfLet(pattern, target, thenBranch, elseBranch) ->
| ExprKind.IfLet { Pattern = pattern
Target = target
Then = thenBranch
Else = elseBranch } ->
let tempId = ctx.GetTempId()
let finalizer = Finalizer.Assign tempId
let tempDecl = buildTempDecl ctx tempId
Expand Down Expand Up @@ -588,11 +602,11 @@ module rec Codegen =
let expr = Expr.Ident { Name = tempId; Loc = None }

(expr, stmts)
| ExprKind.Match(target, cases) ->
| ExprKind.Match { Target = target; Cases = cases } ->
match buildMatchRec ctx target None cases with
| Some expr, stmts -> (expr, stmts)
| None, stmts -> failwith "Failure compiling 'match' expression"
| ExprKind.Assign(op, left, right) ->
| ExprKind.Assign { Op = op; Left = left; Right = right } ->
let leftExpr, leftStmts = buildExpr ctx left
let rightExpr, rightStmts = buildExpr ctx right

Expand Down Expand Up @@ -620,7 +634,7 @@ module rec Codegen =
Loc = None }

(assign, leftStmts @ rightStmts)
| ExprKind.Unary(op, value) ->
| ExprKind.Unary { Op = op; Value = value } ->
let valueExpr, valueStmts = buildExpr ctx value

let op =
Expand Down Expand Up @@ -652,7 +666,7 @@ module rec Codegen =
let bodyBlock = buildBlock ctx body finalizer

let target: Expr =
{ Kind = ExprKind.Identifier "__error__"
{ Kind = ExprKind.Identifier { Name = "__error__" }
Span = dummySpan
InferredType = None }

Expand Down Expand Up @@ -702,7 +716,7 @@ module rec Codegen =
| ExprKind.TemplateLiteral template ->
let tpl, stmts = buildTemplateLiteral ctx template
(Expr.Tpl tpl, stmts)
| ExprKind.TaggedTemplateLiteral(tag, template, _throws) ->
| ExprKind.TaggedTemplateLiteral { Tag = tag; Template = template } ->
let tagExpr, tagStmts = buildExpr ctx tag
let tpl, tplStmts = buildTemplateLiteral ctx template

Expand Down Expand Up @@ -1026,7 +1040,7 @@ module rec Codegen =
// NOTE: We reverse the order of the declarations because the
// if-else chain is built in reverse order.
for decl in List.rev decls do
let checks = decl.Sig.ParamList |> List.map (checkExprFromParam)
let checks = decl.Sig.ParamList |> List.map checkExprFromParam

let check =
checks
Expand Down Expand Up @@ -1137,10 +1151,10 @@ module rec Codegen =
| [ decl ] -> buildFnDecl ctx decl
| decls -> buildOverloadedFnDecl ctx decls
| None -> []
| ClassDecl(_) -> failwith "TODO: buildBlock - ClassDecl"
| EnumDecl(_) -> failwith "TODO: buildBlock - EnumDecl"
| NamespaceDecl(_) -> failwith "TODO: buildBlock - NamespaceDecl"
| InterfaceDecl(_) -> [] // Ignore types when generating JS code
| ClassDecl _ -> failwith "TODO: buildBlock - ClassDecl"
| EnumDecl _ -> failwith "TODO: buildBlock - EnumDecl"
| NamespaceDecl _ -> failwith "TODO: buildBlock - NamespaceDecl"
| InterfaceDecl _ -> [] // Ignore types when generating JS code
| StmtKind.Return expr ->
match expr with
| Some expr ->
Expand Down Expand Up @@ -1472,13 +1486,11 @@ module rec Codegen =
)

items <- item :: items
| FnDecl(_) -> failwith "TODO: buildModuleTypes - FnDecl"
| ClassDecl(_) -> failwith "TODO: buildModuleTypes - ClassDecl"
| EnumDecl(_) -> failwith "TODO: buildModuleTypes - EnumDecl"
| NamespaceDecl(_) ->
failwith "TODO: buildModuleTypes - NamespaceDecl"
| InterfaceDecl(_) ->
failwith "TODO: buildModuleTypes - InterfaceDecl"
| FnDecl _ -> failwith "TODO: buildModuleTypes - FnDecl"
| ClassDecl _ -> failwith "TODO: buildModuleTypes - ClassDecl"
| EnumDecl _ -> failwith "TODO: buildModuleTypes - EnumDecl"
| NamespaceDecl _ -> failwith "TODO: buildModuleTypes - NamespaceDecl"
| InterfaceDecl _ -> failwith "TODO: buildModuleTypes - InterfaceDecl"
| _ -> ()

{ Body = List.rev items
Expand Down Expand Up @@ -1740,8 +1752,8 @@ module rec Codegen =
| PatternKind.Tuple { Elems = elems } -> List.iter walk elems
| PatternKind.Wildcard _ -> ()
| PatternKind.Literal _ -> ()
| PatternKind.Enum(_) -> failwith "TODO: findBinding - Enum"
| PatternKind.Rest(_) -> failwith "TODO: findBinding - Rest"
| PatternKind.Enum _ -> failwith "TODO: findBinding - Enum"
| PatternKind.Rest _ -> failwith "TODO: findBinding - Rest"

walk pat

Expand Down
100 changes: 63 additions & 37 deletions src/Escalier.Data/Library.fs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ module Syntax =
Throws: option<TypeAnn>
IsAsync: bool }

type Identifier = { Name: string }

// TODO: include optional name
type Function =
{ Sig: FuncSig
Expand Down Expand Up @@ -242,6 +244,43 @@ module Syntax =
Args: option<list<Expr>>
mutable Throws: option<Type.Type> }

type ExprWithTypeArgs = { Expr: Expr; TypeArgs: list<TypeAnn> }

type Class =
{ Extends: option<TypeRef>
Implements: option<list<TypeRef>>
Name: option<string>
TypeParams: option<list<TypeParam>>
Elems: list<ClassElem> }

type Index =
{ Target: Expr
Index: Expr
OptChain: bool }

type Member =
{ Target: Expr
Name: string
OptChain: bool }

type IfElse =
{ Condition: Expr
Then: Block
Else: option<BlockOrExpr> } // Expr is only used when chaining if-else expressions

type IfLet =
{ Pattern: Pattern
Target: Expr
Then: Block
Else: option<BlockOrExpr> }

type Match =
{ Target: Expr; Cases: list<MatchCase> }

type Binary = { Op: string; Left: Expr; Right: Expr }

type Unary = { Op: string; Value: Expr }

type Try =
{ Body: Block
Catch: option<list<MatchCase>>
Expand All @@ -252,12 +291,10 @@ module Syntax =
{ Value: Expr
mutable Throws: option<Type.Type> }

type Class =
{ Extends: option<TypeRef>
Implements: option<list<TypeRef>>
Name: option<string>
TypeParams: option<list<TypeParam>>
Elems: list<ClassElem> }
type TaggedTemplateLiteral =
{ Tag: Expr
Template: Common.TemplateLiteral<Expr>
mutable Throws: option<Type.Type> }

type JSXElement =
{ Opening: JSXElementOpening
Expand Down Expand Up @@ -304,40 +341,30 @@ module Syntax =

[<RequireQualifiedAccess>]
type ExprKind =
| Identifier of name: string // TODO: Make an Ident struct
| Identifier of Identifier
| Literal of Common.Literal
| Function of Function
| Call of Call
| New of New
| ExprWithTypeArgs of target: Expr * typeArgs: list<TypeAnn>
| ExprWithTypeArgs of ExprWithTypeArgs
| Object of Common.Object<ObjElem>
| Class of Class
| Tuple of Common.Tuple<Expr>
| Range of Common.Range<Expr>
| Index of target: Expr * index: Expr * opt_chain: bool
| Member of target: Expr * name: string * opt_chain: bool
| IfElse of
condition: Expr *
thenBranch: Block *
elseBranch: option<BlockOrExpr> // Expr is only used when chaining if-else expressions
| IfLet of
pattern: Pattern *
target: Expr *
thenBranch: Block *
elseBranch: option<BlockOrExpr>
| Match of target: Expr * cases: list<MatchCase>
| Assign of op: string * left: Expr * right: Expr
| Binary of op: string * left: Expr * right: Expr // TODO: BinaryOp
| Unary of op: string * value: Expr
| Index of Index
| Member of Member
| IfElse of IfElse
| IfLet of IfLet
| Match of Match
| Assign of Binary
| Binary of Binary
| Unary of Unary
| Try of Try
| Do of body: Block
| Do of Block
| Await of Await
| Throw of value: Expr
| Throw of Expr
| TemplateLiteral of Common.TemplateLiteral<Expr>
| TaggedTemplateLiteral of
tag: Expr *
template: Common.TemplateLiteral<Expr> *
throws: option<Type.Type>
| TaggedTemplateLiteral of TaggedTemplateLiteral
| JSXElement of JSXElement
| JSXFragment of JSXFragment

Expand Down Expand Up @@ -782,7 +809,7 @@ module Type =
| Wildcard -> "_"
| Literal lit -> lit.ToString()
| Rest(target) -> $"...{target}"
| Enum(_) -> failwith "TODO: toString - Pattern.Enum"
| Enum _ -> failwith "TODO: toString - Pattern.Enum"

type FuncParam =
{ Pattern: Pattern
Expand Down Expand Up @@ -1019,7 +1046,7 @@ module Type =
| "||" -> 6
| "&&" -> 5
| _ -> failwith $"Invalid binary operator '{op}'"
| TypeKind.Unary(op, arg) ->
| TypeKind.Unary(op, _arg) ->
match op with
| "+"
| "-"
Expand All @@ -1029,7 +1056,7 @@ module Type =
| TypeKind.TemplateLiteral _ -> 100
| TypeKind.Intrinsic -> 100
| TypeKind.IntrinsicInstance _ -> 100
| TypeKind.Typeof(_) -> failwith "TODO: getPrecedence - TypeKind.Typeof"
| TypeKind.Typeof _ -> failwith "TODO: getPrecedence - TypeKind.Typeof"

let rec printType (ctx: PrintCtx) (t: Type) : string =
let outerPrec = ctx.Precedence
Expand Down Expand Up @@ -1071,14 +1098,13 @@ module Type =
match immutable with
| true -> $"#[{elems}]"
| false -> $"[{elems}]"
| TypeKind.Array { Elem = elem; Length = length } ->
$"{printType ctx elem}[]"
| TypeKind.Array { Elem = elem } -> $"{printType ctx elem}[]"
| TypeKind.RestSpread t -> $"...{printType ctx t}"
| TypeKind.Literal literal -> literal.ToString()
| TypeKind.Range { Min = min; Max = max } ->
$"{printType ctx min}..{printType ctx max}"
| TypeKind.UniqueSymbol id -> "unique symbol"
| TypeKind.UniqueNumber id -> "unique number"
| TypeKind.UniqueSymbol _ -> "unique symbol"
| TypeKind.UniqueNumber _ -> "unique number"
| TypeKind.Union types ->
List.map (printType ctx) types |> String.concat " | "
| TypeKind.Intersection types ->
Expand Down Expand Up @@ -1193,7 +1219,7 @@ module Type =
| _ ->
$"fn {typeParams}({paramList}) -> {ret} throws {printType ctx f.Throws}"

let printMapped (ctx: PrintCtx) (mapped: Mapped) : string =
let printMapped (_ctx: PrintCtx) (mapped: Mapped) : string =
let name =
match mapped.NameType with
| Some(t) -> t.ToString()
Expand Down
Loading

0 comments on commit b277f53

Please sign in to comment.