Skip to content

Commit

Permalink
Ast: narrow PatternExpr
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Apr 20, 2024
1 parent 7a18bd0 commit ddc1e6f
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 54 deletions.
50 changes: 38 additions & 12 deletions src/ast/match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@ import { LexerToken } from '../lexer/lexer'
import { ParseNode, filterNonAstNodes } from '../parser'
import { nameLikeTokens } from '../parser/fns'
import { Typed } from '../semantic'
import { unreachable } from '../util/todo'
import { Expr, buildExpr } from './expr'
import { AstNode } from './index'
import {
BoolLiteral,
CharLiteral,
FloatLiteral,
Identifier,
IntLiteral,
Name,
Operand,
StringInterpolated,
StringLiteral,
buildBool,
buildChar,
buildIdentifier,
buildName,
buildOperand
buildString
} from './operand'
import { Block, buildBlock } from './statement'

Expand Down Expand Up @@ -59,23 +65,43 @@ export const buildPattern = (node: ParseNode): Pattern => {
return { kind: 'pattern', parseNode: node, name, expr }
}

export type PatternExpr = Name | ConPattern | ListPattern | Operand | Hole
export type PatternExpr =
| Name
| ConPattern
| ListPattern
| Hole
| StringLiteral
| StringInterpolated
| CharLiteral
| IntLiteral
| FloatLiteral
| BoolLiteral

export const buildPatternExpr = (node: ParseNode): PatternExpr => {
const n = filterNonAstNodes(node)[0]
if (nameLikeTokens.includes((<LexerToken>n).kind)) {
return buildName(n)
}
if (n.kind === 'con-pattern') {
return buildConPattern(n)
switch (n.kind) {
case 'name':
return buildName(n)
case 'con-pattern':
return buildConPattern(n)
case 'list-pattern':
return buildListPattern(n)
case 'hole':
return buildHole(n)
case 'number':
return buildNumber(n)
case 'string':
return buildString(n)
case 'char':
return buildChar(n)
case 'bool':
return buildBool(n)
default:
return unreachable(n.kind)
}
if (n.kind === 'hole') {
return buildHole(n)
}
if (n.kind === 'number') {
return buildNumber(n)
}
return buildOperand(node)
}

export interface ConPattern extends AstNode<'con-pattern'>, Partial<Typed> {
Expand Down
16 changes: 4 additions & 12 deletions src/ast/operand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ export const buildOperand = (node: ParseNode): Operand => {
case 'string':
return buildString(n)
case 'char':
return buildCharLiteral(n)
return buildChar(n)
case 'number':
return buildNumber(n)
case 'bool':
return buildBoolLiteral(n)
return buildBool(n)
case 'identifier':
return buildIdentifier(n)
}
Expand Down Expand Up @@ -209,31 +209,23 @@ export interface CharLiteral extends AstNode<'char-literal'>, Partial<Typed> {
value: string
}

export const buildCharLiteral = (node: ParseNode): CharLiteral => {
export const buildChar = (node: ParseNode): CharLiteral => {
return { kind: 'char-literal', parseNode: node, value: (<LexerToken>node).value }
}

export interface IntLiteral extends AstNode<'int-literal'>, Partial<Typed> {
value: string
}

export const buildIntLiteral = (node: ParseNode): IntLiteral => {
return { kind: 'int-literal', parseNode: node, value: (<LexerToken>node).value }
}

export interface FloatLiteral extends AstNode<'float-literal'>, Partial<Typed> {
value: string
}

export const buildFloatLiteral = (node: ParseNode): FloatLiteral => {
return { kind: 'float-literal', parseNode: node, value: (<LexerToken>node).value }
}

export interface BoolLiteral extends AstNode<'bool-literal'>, Partial<Typed> {
value: string
}

export const buildBoolLiteral = (node: ParseNode): BoolLiteral => {
export const buildBool = (node: ParseNode): BoolLiteral => {
return { kind: 'bool-literal', parseNode: node, value: (<LexerToken>node).value }
}

Expand Down
14 changes: 1 addition & 13 deletions src/codegen/js/expr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,18 +417,7 @@ export const emitPatternExprCondition = (patternExpr: PatternExpr, ctx: Context,
}
case 'string-interpolated':
return { emit: jsVariable(resultVar, jsError('string-interpolated')), resultVar }
case 'list-expr':
case 'operand-expr':
case 'unary-expr':
case 'binary-expr':
case 'identifier':
case 'name':
case 'if-expr':
case 'if-let-expr':
case 'while-expr':
case 'for-expr':
case 'match-expr':
case 'closure-expr':
return unreachable()
}
}
Expand Down Expand Up @@ -476,14 +465,13 @@ export const emitPattern = (pattern: Pattern, ctx: Context, assignVar: string, p
})
return emitTree([...patterns])
case 'string-interpolated':
case 'list-expr':
case 'list-pattern':
return emitToken(`${jsError(pattern.expr.kind).value};`)
case 'string-literal':
case 'char-literal':
case 'int-literal':
case 'float-literal':
case 'bool-literal':
case 'identifier':
case 'hole':
return emitToken('')
default:
Expand Down
7 changes: 1 addition & 6 deletions src/semantic/exhaust.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { MatchExpr, PatternExpr } from '../ast/match'
import { Context, addError, addWarning } from '../scope'
import { concatVid, idToVid, vidFromScope, vidFromString, vidToString } from '../scope/util'
import { VariantDef, VirtualIdentifierMatch, resolveVid } from '../scope/vid'
import { assert, unreachable } from '../util/todo'
import { assert } from '../util/todo'
import { nonExhaustiveMatchError, unreachableMatchClauseError } from './error'

export interface MatchTree {
Expand Down Expand Up @@ -92,14 +92,11 @@ const matchPattern = (pattern: PatternExpr, tree: MatchTree, ctx: Context): bool
return true
case 'string-literal':
case 'char-literal':
case 'unary-expr':
case 'string-interpolated':
case 'int-literal':
case 'float-literal':
case 'bool-literal':
case 'identifier':
case 'list-pattern':
case 'operand-expr':
// match the node
return true
case 'con-pattern':
Expand Down Expand Up @@ -161,8 +158,6 @@ const matchPattern = (pattern: PatternExpr, tree: MatchTree, ctx: Context): bool
}
}
return matched
default:
return unreachable(pattern.kind)
}
}

Expand Down
12 changes: 1 addition & 11 deletions src/semantic/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import {
typeArgCountMismatchError,
typeError,
unexpectedInInstanceScopeError,
unexpectedPatternKindError,
unexpectedTopLevelStatementError,
unknownTypeError,
unnecessaryPubMethodError,
Expand Down Expand Up @@ -412,16 +411,7 @@ export const checkParam = (param: Param, index: number, ctx: Context): void => {
}
}

switch (param.pattern.expr.kind) {
case 'operand-expr':
case 'unary-expr':
case 'binary-expr':
addError(ctx, unexpectedPatternKindError(ctx, param))
break
default:
checkPattern(param.pattern, param.type, ctx, false)
break
}
checkPattern(param.pattern, param.type, ctx, false)
}

const checkTraitDef = (traitDef: TraitDef, ctx: Context) => {
Expand Down

0 comments on commit ddc1e6f

Please sign in to comment.