Browse Source

Add support for unary operators

master
Forest Belton 3 years ago
parent
commit
ff7dba498c
5 changed files with 38 additions and 8 deletions
  1. +2
    -0
      example.gby
  2. +2
    -2
      lib/asm.ts
  3. +9
    -1
      lib/ast.d.ts
  4. +14
    -3
      lib/ir.ts
  5. +11
    -2
      lib/parser.pegjs

+ 2
- 0
example.gby View File

@ -1,3 +1,5 @@
u8 x; u8 x;
u8 y;
x <- 1; x <- 1;
y <- -x;

+ 2
- 2
lib/asm.ts View File

@ -129,14 +129,14 @@ export const convertASM_SSA_Unary = (state: ASMState, ssa: SSAUnary): void => {
} }
switch (ssa.op) { switch (ssa.op) {
case '-':
case 'arith_negate':
state.insns.push( state.insns.push(
`CPL`, `CPL`,
`INC A`, `INC A`,
) )
break break
case '~':
case 'bit_negate':
state.insns.push( state.insns.push(
`CPL` `CPL`
) )

+ 9
- 1
lib/ast.d.ts View File

@ -30,7 +30,15 @@ type AStmt = {
} }
// Expressions // Expressions
export type Expr = number
export type Expr = UnaryExpr | BasicExpr
type UnaryExpr = {
type: "unary",
op: string,
arg: Expr,
}
type BasicExpr = number | string
// Attributes // Attributes
export type Attr = { export type Attr = {

+ 14
- 3
lib/ir.ts View File

@ -1,6 +1,5 @@
import type { AssignStmt, Expr, Stmt } from "./ast" import type { AssignStmt, Expr, Stmt } from "./ast"
// dest <- op(x, y)
type Operand = string | number type Operand = string | number
type ASSA<Data> = { dest: string, source: Operand } & Data type ASSA<Data> = { dest: string, source: Operand } & Data
@ -44,9 +43,21 @@ export const convertAssignStmt = (state: IRState, stmt: AssignStmt): Array
return expr_stmts return expr_stmts
} }
export const convertExpr = (state: IRState, expr: Expr): [string, Array<SSA>] => {
export const convertExpr = (state: IRState, expr: Expr): [string | number, Array<SSA>] => {
if (typeof expr === "number" || typeof expr === "string") {
return [expr, []]
}
const [source, expr_stmts] = convertExpr(state, expr.arg)
const name = `temp${state.nextID++}` const name = `temp${state.nextID++}`
return [name, [{ dest: name, source: expr }]]
expr_stmts.push({
dest: name,
source,
op: expr.op,
})
return [name, expr_stmts]
} }
export const prettyPrintIR = (ssa: SSA): string => { export const prettyPrintIR = (ssa: SSA): string => {

+ 11
- 2
lib/parser.pegjs View File

@ -3,6 +3,8 @@
const attr = (name, args) => ({ name, args }) const attr = (name, args) => ({ name, args })
const stmt = (stmt_type, args) => ({ type: "stmt", stmt_type, args }) const stmt = (stmt_type, args) => ({ type: "stmt", stmt_type, args })
const decl = (decl_type, name, attrs, args) => ({ type: "decl", decl_type, name, attrs: attrs || [], args }) const decl = (decl_type, name, attrs, args) => ({ type: "decl", decl_type, name, attrs: attrs || [], args })
const uexpr = (op, arg) => ({ type: "unary", op, arg })
const bexpr = (op, arg1, arg2) => ({ type: "binary", op, arg1, arg2 })
} }
Program = WS @(Decl / Stmt)* WS Program = WS @(Decl / Stmt)* WS
@ -16,8 +18,13 @@ Stmt = @AssignStmt SEMI
AssignStmt = name:Ident ASSIGN expr:Expr { return stmt("assign", { name, expr }) } AssignStmt = name:Ident ASSIGN expr:Expr { return stmt("assign", { name, expr }) }
// Expressions // Expressions
Expr = BaseExpr
BaseExpr = Number
Expr = UnaryExpr
UnaryExpr = op:UnaryOp? e:BaseExpr { return op ? uexpr(op, e) : e }
UnaryOp = TILDE { return "bit_negate" }
/ MINUS { return "arith_negate" }
BaseExpr = Ident / Number / LPAREN @Expr RPAREN
// Attributes // Attributes
Attrs = LATTR @AttrList RATTR Attrs = LATTR @AttrList RATTR
@ -44,6 +51,8 @@ U8 = @'u8' WS
U16 = @'u16' WS U16 = @'u16' WS
// Terminal symbols // Terminal symbols
TILDE = '~' WS
MINUS = '-' WS
SEMI = ';' WS SEMI = ';' WS
ASSIGN = '<-' WS ASSIGN = '<-' WS
LPAREN = '(' WS LPAREN = '(' WS

Loading…
Cancel
Save