parser/cgen: is keyword
parent
cc9828b481
commit
af224b4933
|
@ -196,6 +196,9 @@ pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type {
|
||||||
left_type := c.expr(infix_expr.left)
|
left_type := c.expr(infix_expr.left)
|
||||||
infix_expr.left_type = left_type
|
infix_expr.left_type = left_type
|
||||||
c.expected_type = left_type
|
c.expected_type = left_type
|
||||||
|
if infix_expr.op == .key_is {
|
||||||
|
return table.bool_type
|
||||||
|
}
|
||||||
right_type := c.expr(infix_expr.right)
|
right_type := c.expr(infix_expr.right)
|
||||||
infix_expr.right_type = right_type
|
infix_expr.right_type = right_type
|
||||||
right := c.table.get_type_symbol(right_type)
|
right := c.table.get_type_symbol(right_type)
|
||||||
|
@ -1709,6 +1712,9 @@ pub fn (c mut Checker) warn(s string, pos token.Position) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (c mut Checker) error(message string, pos token.Position) {
|
pub fn (c mut Checker) error(message string, pos token.Position) {
|
||||||
|
if c.pref.is_verbose {
|
||||||
|
print_backtrace()
|
||||||
|
}
|
||||||
c.warn_or_error(message, pos, false)
|
c.warn_or_error(message, pos, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,15 +126,10 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
g.finish()
|
g.finish()
|
||||||
return g.hashes() +
|
return g.hashes() + '\n// V typedefs:\n' + g.typedefs.str() + '\n// V typedefs2:\n' + g.typedefs2.str() +
|
||||||
'\n// V typedefs:\n' + g.typedefs.str() +
|
'\n// V cheaders:\n' + g.cheaders.str() + '\n// V includes:\n' + g.includes.str() + '\n// V definitions:\n' +
|
||||||
'\n// V typedefs2:\n' + g.typedefs2.str() +
|
g.definitions.str() + '\n// V gowrappers:\n' + g.gowrappers.str() + '\n// V stringliterals:\n' +
|
||||||
'\n// V cheaders:\n' + g.cheaders.str() +
|
g.stringliterals.str() + '\n// V out\n' + g.out.str()
|
||||||
'\n// V includes:\n' + g.includes.str() +
|
|
||||||
'\n// V definitions:\n' + g.definitions.str() +
|
|
||||||
'\n// V gowrappers:\n' + g.gowrappers.str() +
|
|
||||||
'\n// V stringliterals:\n' + g.stringliterals.str() +
|
|
||||||
'\n// V out\n' + g.out.str()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (g Gen) hashes() string {
|
pub fn (g Gen) hashes() string {
|
||||||
|
@ -1211,6 +1206,10 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) {
|
||||||
// string + string, string == string etc
|
// string + string, string == string etc
|
||||||
// g.infix_op = node.op
|
// g.infix_op = node.op
|
||||||
left_sym := g.table.get_type_symbol(node.left_type)
|
left_sym := g.table.get_type_symbol(node.left_type)
|
||||||
|
if node.op == .key_is {
|
||||||
|
g.is_expr(node)
|
||||||
|
return
|
||||||
|
}
|
||||||
right_sym := g.table.get_type_symbol(node.right_type)
|
right_sym := g.table.get_type_symbol(node.right_type)
|
||||||
if node.left_type == table.string_type_idx && node.op != .key_in && node.op != .not_in {
|
if node.left_type == table.string_type_idx && node.op != .key_in && node.op != .not_in {
|
||||||
fn_name := match node.op {
|
fn_name := match node.op {
|
||||||
|
@ -2828,6 +2827,12 @@ fn (g mut Gen) go_stmt(node ast.GoStmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (g mut Gen) is_expr(node ast.InfixExpr) {
|
||||||
|
g.expr(node.left)
|
||||||
|
g.write('.typ == ')
|
||||||
|
g.expr(node.right)
|
||||||
|
}
|
||||||
|
|
||||||
// already generated styp, reuse it
|
// already generated styp, reuse it
|
||||||
fn (g mut Gen) gen_str_for_type(sym table.TypeSymbol, styp string) {
|
fn (g mut Gen) gen_str_for_type(sym table.TypeSymbol, styp string) {
|
||||||
if sym.has_method('str') || styp in g.str_types {
|
if sym.has_method('str') || styp in g.str_types {
|
||||||
|
|
|
@ -21,7 +21,7 @@ mut:
|
||||||
peek_tok token.Token
|
peek_tok token.Token
|
||||||
table &table.Table
|
table &table.Table
|
||||||
is_c bool
|
is_c bool
|
||||||
is_js bool
|
is_js bool
|
||||||
inside_if bool
|
inside_if bool
|
||||||
inside_for bool
|
inside_for bool
|
||||||
inside_fn bool
|
inside_fn bool
|
||||||
|
@ -39,6 +39,7 @@ mut:
|
||||||
inside_match bool // to separate `match A { }` from `Struct{}`
|
inside_match bool // to separate `match A { }` from `Struct{}`
|
||||||
inside_match_case bool // to separate `match_expr { }` from `Struct{}`
|
inside_match_case bool // to separate `match_expr { }` from `Struct{}`
|
||||||
is_stmt_ident bool // true while the beginning of a statement is an ident/selector
|
is_stmt_ident bool // true while the beginning of a statement is an ident/selector
|
||||||
|
inside_is bool // `is Type`, expecting type
|
||||||
}
|
}
|
||||||
|
|
||||||
// for tests
|
// for tests
|
||||||
|
@ -616,6 +617,11 @@ fn (p mut Parser) struct_init(short_syntax bool) ast.StructInit {
|
||||||
|
|
||||||
pub fn (p mut Parser) name_expr() ast.Expr {
|
pub fn (p mut Parser) name_expr() ast.Expr {
|
||||||
var node := ast.Expr{}
|
var node := ast.Expr{}
|
||||||
|
if p.inside_is {
|
||||||
|
return ast.Type{
|
||||||
|
typ: p.parse_type()
|
||||||
|
}
|
||||||
|
}
|
||||||
is_c := p.tok.lit == 'C'
|
is_c := p.tok.lit == 'C'
|
||||||
is_js := p.tok.lit == 'JS'
|
is_js := p.tok.lit == 'JS'
|
||||||
var mod := ''
|
var mod := ''
|
||||||
|
@ -635,8 +641,8 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
||||||
return p.string_expr()
|
return p.string_expr()
|
||||||
}
|
}
|
||||||
known_var := p.scope.known_var(p.tok.lit)
|
known_var := p.scope.known_var(p.tok.lit)
|
||||||
if p.peek_tok.kind == .dot && !known_var && (is_c || is_js || p.known_import(p.tok.lit) || p.mod.all_after('.') ==
|
if p.peek_tok.kind == .dot && !known_var && (is_c || is_js || p.known_import(p.tok.lit) ||
|
||||||
p.tok.lit) {
|
p.mod.all_after('.') == p.tok.lit) {
|
||||||
if is_c {
|
if is_c {
|
||||||
mod = 'C'
|
mod = 'C'
|
||||||
} else if is_js {
|
} else if is_js {
|
||||||
|
@ -1044,7 +1050,11 @@ fn (p mut Parser) infix_expr(left ast.Expr) ast.Expr {
|
||||||
pos := p.tok.position()
|
pos := p.tok.position()
|
||||||
p.next()
|
p.next()
|
||||||
var right := ast.Expr{}
|
var right := ast.Expr{}
|
||||||
|
if op == .key_is {
|
||||||
|
p.inside_is = true
|
||||||
|
}
|
||||||
right = p.expr(precedence)
|
right = p.expr(precedence)
|
||||||
|
p.inside_is = false
|
||||||
var expr := ast.Expr{}
|
var expr := ast.Expr{}
|
||||||
expr = ast.InfixExpr{
|
expr = ast.InfixExpr{
|
||||||
left: left
|
left: left
|
||||||
|
@ -1511,7 +1521,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl {
|
||||||
if p.tok.kind != .lpar {
|
if p.tok.kind != .lpar {
|
||||||
p.error('consts must be grouped, e.g.\nconst (\n\ta = 1\n)')
|
p.error('consts must be grouped, e.g.\nconst (\n\ta = 1\n)')
|
||||||
}
|
}
|
||||||
p.next() // (
|
p.next() // (
|
||||||
var fields := []ast.ConstField
|
var fields := []ast.ConstField
|
||||||
for p.tok.kind != .rpar {
|
for p.tok.kind != .rpar {
|
||||||
if p.tok.kind == .comment {
|
if p.tok.kind == .comment {
|
||||||
|
|
|
@ -14,7 +14,7 @@ fn foo(b int, a mut []int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_mut() {
|
fn test_mut() {
|
||||||
mut numbers := [1, 2, 3]
|
var numbers := [1, 2, 3]
|
||||||
foo(7, mut numbers)
|
foo(7, mut numbers)
|
||||||
assert numbers.len == 3
|
assert numbers.len == 3
|
||||||
// TODO bring back once << works with mutable args
|
// TODO bring back once << works with mutable args
|
||||||
|
@ -23,15 +23,16 @@ fn test_mut() {
|
||||||
// assert numbers[3] == 4
|
// assert numbers[3] == 4
|
||||||
println(numbers)
|
println(numbers)
|
||||||
n := 1
|
n := 1
|
||||||
mut b := &n
|
var b := &n
|
||||||
*b = 10
|
//
|
||||||
//mut b := mut a
|
(*b) = 10
|
||||||
//b = 10
|
// mut b := mut a
|
||||||
|
// b = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_mut_2() {
|
fn test_mut_2() {
|
||||||
zero := 0
|
zero := 0
|
||||||
mut b := B{}
|
var b := B{}
|
||||||
b.a << A{}
|
b.a << A{}
|
||||||
b.a[0].v = [9, 8, 7]
|
b.a[0].v = [9, 8, 7]
|
||||||
b.a[0].v << 6
|
b.a[0].v << 6
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
type Expr = IfExpr | IntegerLiteral
|
||||||
|
|
||||||
|
struct IfExpr {
|
||||||
|
pos int
|
||||||
|
}
|
||||||
|
|
||||||
|
struct IntegerLiteral {
|
||||||
|
val string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle(e Expr) string {
|
||||||
|
assert e is IntegerLiteral
|
||||||
|
if e is IntegerLiteral {
|
||||||
|
println('int')
|
||||||
|
}
|
||||||
|
match e {
|
||||||
|
IntegerLiteral {
|
||||||
|
return 'int'
|
||||||
|
}
|
||||||
|
IfExpr {
|
||||||
|
return 'if'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_expr() {
|
||||||
|
expr := IntegerLiteral{'12'}
|
||||||
|
assert handle(expr) == 'int'
|
||||||
|
// assert expr is IntegerLiteral
|
||||||
|
}
|
|
@ -101,6 +101,7 @@ pub enum Kind {
|
||||||
key_import_const
|
key_import_const
|
||||||
key_in
|
key_in
|
||||||
key_interface
|
key_interface
|
||||||
|
key_is
|
||||||
// key_it
|
// key_it
|
||||||
key_match
|
key_match
|
||||||
key_module
|
key_module
|
||||||
|
@ -246,6 +247,7 @@ fn build_token_str() []string {
|
||||||
s[Kind.key_select] = 'select'
|
s[Kind.key_select] = 'select'
|
||||||
s[Kind.key_none] = 'none'
|
s[Kind.key_none] = 'none'
|
||||||
s[Kind.key_offsetof] = '__offsetof'
|
s[Kind.key_offsetof] = '__offsetof'
|
||||||
|
s[Kind.key_is] = 'is'
|
||||||
s[Kind.key_var] = 'var'
|
s[Kind.key_var] = 'var'
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
@ -385,7 +387,7 @@ pub fn (tok Token) precedence() int {
|
||||||
.left_shift_assign, .right_shift_assign, .mult_assign, .xor_assign {
|
.left_shift_assign, .right_shift_assign, .mult_assign, .xor_assign {
|
||||||
return int(Precedence.assign)
|
return int(Precedence.assign)
|
||||||
}
|
}
|
||||||
.key_in, .not_in, .key_as {
|
.key_in, .not_in, .key_as, .key_is {
|
||||||
return int(Precedence.in_as)
|
return int(Precedence.in_as)
|
||||||
}
|
}
|
||||||
.logical_or, .and {
|
.logical_or, .and {
|
||||||
|
@ -425,7 +427,7 @@ pub fn (k Kind) is_start_of_type() bool {
|
||||||
pub fn (kind Kind) is_infix() bool {
|
pub fn (kind Kind) is_infix() bool {
|
||||||
return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .key_in,
|
return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .key_in,
|
||||||
//
|
//
|
||||||
.key_as, .ge, .le, .logical_or, .xor, .not_in,
|
.key_as, .ge, .le, .logical_or, .xor, .not_in, .key_is,
|
||||||
//
|
//
|
||||||
.and, .dot, .pipe, .amp, .left_shift, .right_shift]
|
.and, .dot, .pipe, .amp, .left_shift, .right_shift]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue