2019-12-22 02:34:37 +01:00
|
|
|
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
|
|
|
// Use of this source code is governed by an MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
|
|
|
module ast
|
|
|
|
|
|
|
|
import (
|
2019-12-27 05:43:17 +01:00
|
|
|
v.token
|
2019-12-27 08:52:20 +01:00
|
|
|
v.types
|
2019-12-22 02:34:37 +01:00
|
|
|
)
|
|
|
|
|
2019-12-29 07:24:17 +01:00
|
|
|
pub type Expr = BinaryExpr | UnaryExpr | IfExpr | StringLiteral | IntegerLiteral |
|
2019-12-29 08:51:55 +01:00
|
|
|
FloatLiteral | Ident | CallExpr | BoolLiteral
|
2019-12-28 14:11:05 +01:00
|
|
|
|
2019-12-28 19:16:04 +01:00
|
|
|
pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt | AssignStmt
|
2019-12-28 14:11:05 +01:00
|
|
|
// Stand-alone expression in a statement list.
|
|
|
|
pub struct ExprStmt {
|
|
|
|
pub:
|
|
|
|
expr Expr
|
|
|
|
}
|
2019-12-22 02:34:37 +01:00
|
|
|
|
2019-12-26 11:21:41 +01:00
|
|
|
pub struct IntegerLiteral {
|
2019-12-26 03:40:18 +01:00
|
|
|
pub:
|
|
|
|
val int
|
|
|
|
}
|
2019-12-24 18:54:43 +01:00
|
|
|
|
2019-12-27 10:03:29 +01:00
|
|
|
pub struct FloatLiteral {
|
|
|
|
pub:
|
2019-12-28 09:43:22 +01:00
|
|
|
// val f64
|
2019-12-27 10:03:29 +01:00
|
|
|
val string
|
|
|
|
}
|
|
|
|
|
2019-12-24 18:54:43 +01:00
|
|
|
pub struct StringLiteral {
|
|
|
|
pub:
|
|
|
|
val string
|
|
|
|
}
|
2019-12-22 02:34:37 +01:00
|
|
|
|
2019-12-29 08:51:55 +01:00
|
|
|
pub struct BoolLiteral {
|
|
|
|
pub:
|
|
|
|
val bool
|
|
|
|
}
|
|
|
|
|
2019-12-28 11:02:06 +01:00
|
|
|
// module declaration
|
2019-12-28 09:15:32 +01:00
|
|
|
pub struct Module {
|
|
|
|
pub:
|
2019-12-28 09:43:22 +01:00
|
|
|
name string
|
|
|
|
path string
|
|
|
|
expr Expr
|
2019-12-28 09:15:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// import statement
|
|
|
|
pub struct Import {
|
|
|
|
pub:
|
2019-12-28 09:43:22 +01:00
|
|
|
name string
|
|
|
|
expr Expr
|
2019-12-28 09:15:32 +01:00
|
|
|
// imports map[string]string
|
|
|
|
}
|
|
|
|
|
2019-12-29 07:24:17 +01:00
|
|
|
pub struct Arg {
|
|
|
|
pub:
|
|
|
|
typ types.Type
|
|
|
|
name string
|
|
|
|
}
|
|
|
|
|
2019-12-27 13:57:49 +01:00
|
|
|
pub struct FnDecl {
|
|
|
|
pub:
|
|
|
|
name string
|
2019-12-28 14:11:05 +01:00
|
|
|
stmts []Stmt
|
2019-12-28 09:43:22 +01:00
|
|
|
typ types.Type
|
2019-12-29 07:24:17 +01:00
|
|
|
args []Arg
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct CallExpr {
|
|
|
|
pub:
|
|
|
|
name string
|
|
|
|
args []Expr
|
2019-12-27 13:57:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Return {
|
|
|
|
pub:
|
|
|
|
expr Expr
|
|
|
|
}
|
|
|
|
|
2019-12-22 02:34:37 +01:00
|
|
|
/*
|
|
|
|
pub enum Expr {
|
|
|
|
Binary(BinaryExpr)
|
|
|
|
If(IfExpr)
|
|
|
|
Integer(IntegerExpr)
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2019-12-24 18:54:43 +01:00
|
|
|
/*
|
2019-12-22 02:34:37 +01:00
|
|
|
pub struct Stmt {
|
|
|
|
pos int
|
|
|
|
//end int
|
|
|
|
}
|
2019-12-24 18:54:43 +01:00
|
|
|
*/
|
|
|
|
|
2019-12-28 09:43:22 +01:00
|
|
|
|
2019-12-24 18:54:43 +01:00
|
|
|
pub struct VarDecl {
|
|
|
|
pub:
|
|
|
|
name string
|
|
|
|
expr Expr
|
2019-12-28 09:43:22 +01:00
|
|
|
typ types.Type
|
2019-12-24 18:54:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Program {
|
|
|
|
pub:
|
2019-12-28 14:11:05 +01:00
|
|
|
stmts []Stmt
|
2019-12-24 18:54:43 +01:00
|
|
|
}
|
2019-12-28 14:11:05 +01:00
|
|
|
|
2019-12-22 02:34:37 +01:00
|
|
|
// A single identifier
|
2019-12-28 14:11:05 +01:00
|
|
|
pub struct Ident {
|
|
|
|
pub:
|
|
|
|
name string
|
2019-12-28 09:15:32 +01:00
|
|
|
tok_kind token.TokenKind
|
2019-12-28 09:43:22 +01:00
|
|
|
value string
|
2019-12-22 02:34:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct BinaryExpr {
|
|
|
|
pub:
|
2019-12-28 19:16:04 +01:00
|
|
|
// tok_kind token.TokenKind
|
|
|
|
// op BinaryOp
|
|
|
|
op token.TokenKind
|
|
|
|
left Expr
|
2019-12-28 09:43:22 +01:00
|
|
|
// left_type Type
|
2019-12-28 19:16:04 +01:00
|
|
|
right Expr
|
2019-12-28 09:43:22 +01:00
|
|
|
// right_type Type
|
2019-12-22 02:34:37 +01:00
|
|
|
}
|
|
|
|
|
2019-12-25 13:39:58 +01:00
|
|
|
pub struct UnaryExpr {
|
|
|
|
pub:
|
2019-12-28 09:43:22 +01:00
|
|
|
// tok_kind token.TokenKind
|
|
|
|
// op BinaryOp
|
|
|
|
op token.TokenKind
|
|
|
|
left Expr
|
2019-12-25 13:39:58 +01:00
|
|
|
}
|
|
|
|
|
2019-12-28 19:16:04 +01:00
|
|
|
pub struct IfExpr {
|
2019-12-29 08:51:55 +01:00
|
|
|
pub:
|
2019-12-28 09:15:32 +01:00
|
|
|
tok_kind token.TokenKind
|
2019-12-28 09:43:22 +01:00
|
|
|
cond Expr
|
2019-12-29 08:51:55 +01:00
|
|
|
stmts []Stmt
|
2019-12-28 09:43:22 +01:00
|
|
|
else_ []Stmt
|
2019-12-22 02:34:37 +01:00
|
|
|
}
|
|
|
|
|
2019-12-28 19:16:04 +01:00
|
|
|
pub struct ReturnStmt {
|
2019-12-28 09:43:22 +01:00
|
|
|
tok_kind token.TokenKind // or pos
|
|
|
|
results []Expr
|
2019-12-22 02:34:37 +01:00
|
|
|
}
|
|
|
|
|
2019-12-28 19:16:04 +01:00
|
|
|
pub struct AssignStmt {
|
|
|
|
pub:
|
|
|
|
left Expr
|
|
|
|
right Expr
|
|
|
|
op token.TokenKind
|
|
|
|
}
|
|
|
|
|
2019-12-25 13:39:58 +01:00
|
|
|
// string representaiton of expr
|
|
|
|
pub fn (x Expr) str() string {
|
|
|
|
match x {
|
|
|
|
BinaryExpr {
|
2019-12-26 11:27:35 +01:00
|
|
|
return '(${it.left.str()} $it.op.str() ${it.right.str()})'
|
2019-12-25 13:39:58 +01:00
|
|
|
}
|
|
|
|
UnaryExpr {
|
2019-12-26 11:27:35 +01:00
|
|
|
return it.left.str() + it.op.str()
|
|
|
|
}
|
|
|
|
IntegerLiteral {
|
|
|
|
return it.val.str()
|
|
|
|
}
|
|
|
|
IntegerLiteral {
|
|
|
|
return '"$it.val"'
|
2019-12-25 13:39:58 +01:00
|
|
|
}
|
2019-12-28 09:43:22 +01:00
|
|
|
else {
|
|
|
|
return ''
|
|
|
|
}
|
2019-12-25 13:39:58 +01:00
|
|
|
}
|
2019-12-22 02:34:37 +01:00
|
|
|
}
|
|
|
|
|
2019-12-28 14:11:05 +01:00
|
|
|
pub fn (node Stmt) str() string {
|
|
|
|
match node {
|
|
|
|
VarDecl {
|
|
|
|
return it.name + ' = ' + it.expr.str()
|
|
|
|
}
|
|
|
|
ExprStmt {
|
|
|
|
return it.expr.str()
|
|
|
|
}
|
|
|
|
FnDecl {
|
|
|
|
return 'fn ${it.name}() { $it.stmts.len stmts }'
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return '[unhandled stmt str]'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-26 03:40:18 +01:00
|
|
|
/*
|
|
|
|
enum BinaryOp {
|
|
|
|
sum
|
|
|
|
difference
|
|
|
|
product
|
|
|
|
quotient
|
|
|
|
remainder
|
|
|
|
bitwise_and
|
|
|
|
bitwise_or
|
|
|
|
bitwise_xor
|
|
|
|
left_shift
|
|
|
|
right_shift
|
|
|
|
|
|
|
|
equality
|
|
|
|
inequality
|
|
|
|
less_than
|
|
|
|
less_than_or_equal
|
|
|
|
more_than
|
|
|
|
more_than_or_equal
|
|
|
|
|
|
|
|
in_check
|
|
|
|
|
|
|
|
//These are suffixed with `bool` to prevent conflict with the keyword `or`
|
|
|
|
and_bool
|
|
|
|
or_bool
|
|
|
|
}
|
|
|
|
*/
|