Add array indexing

This commit is contained in:
Smaug123
2024-01-22 22:43:44 +00:00
parent 04edaf65ed
commit 8cee6accf9
5 changed files with 90 additions and 16 deletions

View File

@@ -6,6 +6,7 @@ type Expr =
| Times of Expr * Expr
| UnaryMinus of Expr
| Minus of Expr * Expr
| Equal of Expr * Expr
| Int of int
| FunctionCall of Expr * Expr
| Var of string
@@ -13,10 +14,12 @@ type Expr =
| Paren of Expr
| IfThenElse of Expr * Expr * Expr
| IfThen of Expr * Expr
| ArrayIndex of Expr * Expr
[<RequireQualifiedAccess>]
module Expr =
let plus a b = Expr.Plus (a, b)
let equal a b = Expr.Equal (a, b)
let times a b = Expr.Times (a, b)
let unaryMinus a = Expr.UnaryMinus a
let minus a b = Expr.Minus (a, b)
@@ -25,6 +28,7 @@ module Expr =
let var name = Expr.Var name
let factorial a = Expr.Factorial a
let paren a = Expr.Paren a
let arrayIndex a b = Expr.ArrayIndex (a, b)
let ifThenElse ifClause thenClause elseClause =
Expr.IfThenElse (ifClause, thenClause, elseClause)
@@ -36,9 +40,12 @@ type TokenType =
| Plus
| Minus
| Times
| Equal
| ConstInt
| LeftBracket
| RightBracket
| ArrayIndex
| RightSquareBracket
| Var
| Factorial
| If
@@ -74,4 +81,6 @@ module Token =
| '+' -> standalone' TokenType.Plus i |> Some
| '-' -> standalone' TokenType.Minus i |> Some
| '!' -> standalone' TokenType.Factorial i |> Some
| '=' -> standalone' TokenType.Equal i |> Some
| ']' -> standalone' TokenType.RightSquareBracket i |> Some
| _ -> None

View File

@@ -20,24 +20,29 @@ module Example =
| TokenType.Plus
| TokenType.Minus
| TokenType.Times
| TokenType.Equal
| TokenType.Factorial
| TokenType.If
| TokenType.Then
| TokenType.Else
| TokenType.ArrayIndex
| TokenType.RightSquareBracket
| TokenType.LeftBracket
| TokenType.RightBracket -> None
let parser =
Parser.make (fun token -> token.Type) atom
|> Parser.withUnaryPostfix TokenType.Factorial (7, ()) Expr.factorial
|> Parser.withUnaryPrefix TokenType.Plus ((), 5) id
|> Parser.withUnaryPrefix TokenType.Minus ((), 5) Expr.unaryMinus
|> Parser.withInfix TokenType.Plus (1, 2) Expr.plus
|> Parser.withInfix TokenType.Minus (1, 2) Expr.minus
|> Parser.withInfix TokenType.Times (1, 2) Expr.times
|> Parser.withUnaryPostfix TokenType.Factorial (11, ()) Expr.factorial
|> Parser.withUnaryPrefix TokenType.Plus ((), 9) id
|> Parser.withUnaryPrefix TokenType.Minus ((), 9) Expr.unaryMinus
|> Parser.withInfix TokenType.Plus (5, 6) Expr.plus
|> Parser.withInfix TokenType.Minus (5, 6) Expr.minus
|> Parser.withInfix TokenType.Times (7, 8) Expr.times
|> Parser.withInfix TokenType.Equal (2, 1) Expr.equal
|> Parser.withBracketLike
TokenType.LeftBracket
{
ConsumeBeforeInitialToken = false
ConsumeAfterFinalToken = false
BoundaryTokens = [ TokenType.RightBracket ]
Construct = Seq.exactlyOne >> Expr.paren
@@ -45,6 +50,7 @@ module Example =
|> Parser.withBracketLike
TokenType.If
{
ConsumeBeforeInitialToken = false
ConsumeAfterFinalToken = true
BoundaryTokens = [ TokenType.Then ; TokenType.Else ]
Construct =
@@ -56,6 +62,7 @@ module Example =
|> Parser.withBracketLike
TokenType.If
{
ConsumeBeforeInitialToken = false
ConsumeAfterFinalToken = true
BoundaryTokens = [ TokenType.Then ]
Construct =
@@ -64,3 +71,15 @@ module Example =
| [ ifClause ; thenClause ] -> Expr.ifThen ifClause thenClause
| _ -> failwith "logic error"
}
|> Parser.withBracketLike
TokenType.ArrayIndex
{
ConsumeBeforeInitialToken = true
ConsumeAfterFinalToken = false
BoundaryTokens = [ TokenType.RightSquareBracket ]
Construct =
fun s ->
match s with
| [ arg ; contents ] -> Expr.arrayIndex arg contents
| _ -> failwith "logic error"
}

View File

@@ -28,6 +28,9 @@ module Lexer =
yield Token.standalone TokenType.ConstInt startI (i - startI)
| _, ' ' -> i <- i + 1
| _, '.' when i < s.Length - 1 && s.[i + 1] = '[' ->
yield Token.standalone TokenType.ArrayIndex i 2
i <- i + 2
| _, 'i' when i < s.Length - 1 && s.[i + 1] = 'f' ->
yield Token.standalone TokenType.If i 2
i <- i + 2