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)
|
||||
infix_expr.left_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)
|
||||
infix_expr.right_type = 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) {
|
||||
if c.pref.is_verbose {
|
||||
print_backtrace()
|
||||
}
|
||||
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()
|
||||
return g.hashes() +
|
||||
'\n// V typedefs:\n' + g.typedefs.str() +
|
||||
'\n// V typedefs2:\n' + g.typedefs2.str() +
|
||||
'\n// V cheaders:\n' + g.cheaders.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()
|
||||
return g.hashes() + '\n// V typedefs:\n' + g.typedefs.str() + '\n// V typedefs2:\n' + g.typedefs2.str() +
|
||||
'\n// V cheaders:\n' + g.cheaders.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 {
|
||||
|
@ -1211,6 +1206,10 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) {
|
|||
// string + string, string == string etc
|
||||
// g.infix_op = node.op
|
||||
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)
|
||||
if node.left_type == table.string_type_idx && node.op != .key_in && node.op != .not_in {
|
||||
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
|
||||
fn (g mut Gen) gen_str_for_type(sym table.TypeSymbol, styp string) {
|
||||
if sym.has_method('str') || styp in g.str_types {
|
||||
|
|
|
@ -21,7 +21,7 @@ mut:
|
|||
peek_tok token.Token
|
||||
table &table.Table
|
||||
is_c bool
|
||||
is_js bool
|
||||
is_js bool
|
||||
inside_if bool
|
||||
inside_for bool
|
||||
inside_fn bool
|
||||
|
@ -39,6 +39,7 @@ mut:
|
|||
inside_match bool // to separate `match A { }` 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
|
||||
inside_is bool // `is Type`, expecting type
|
||||
}
|
||||
|
||||
// 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 {
|
||||
var node := ast.Expr{}
|
||||
if p.inside_is {
|
||||
return ast.Type{
|
||||
typ: p.parse_type()
|
||||
}
|
||||
}
|
||||
is_c := p.tok.lit == 'C'
|
||||
is_js := p.tok.lit == 'JS'
|
||||
var mod := ''
|
||||
|
@ -635,8 +641,8 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
|||
return p.string_expr()
|
||||
}
|
||||
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('.') ==
|
||||
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('.') == p.tok.lit) {
|
||||
if is_c {
|
||||
mod = 'C'
|
||||
} else if is_js {
|
||||
|
@ -1044,7 +1050,11 @@ fn (p mut Parser) infix_expr(left ast.Expr) ast.Expr {
|
|||
pos := p.tok.position()
|
||||
p.next()
|
||||
var right := ast.Expr{}
|
||||
if op == .key_is {
|
||||
p.inside_is = true
|
||||
}
|
||||
right = p.expr(precedence)
|
||||
p.inside_is = false
|
||||
var expr := ast.Expr{}
|
||||
expr = ast.InfixExpr{
|
||||
left: left
|
||||
|
@ -1511,7 +1521,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl {
|
|||
if p.tok.kind != .lpar {
|
||||
p.error('consts must be grouped, e.g.\nconst (\n\ta = 1\n)')
|
||||
}
|
||||
p.next() // (
|
||||
p.next() // (
|
||||
var fields := []ast.ConstField
|
||||
for p.tok.kind != .rpar {
|
||||
if p.tok.kind == .comment {
|
||||
|
|
|
@ -14,7 +14,7 @@ fn foo(b int, a mut []int) {
|
|||
}
|
||||
|
||||
fn test_mut() {
|
||||
mut numbers := [1, 2, 3]
|
||||
var numbers := [1, 2, 3]
|
||||
foo(7, mut numbers)
|
||||
assert numbers.len == 3
|
||||
// TODO bring back once << works with mutable args
|
||||
|
@ -23,15 +23,16 @@ fn test_mut() {
|
|||
// assert numbers[3] == 4
|
||||
println(numbers)
|
||||
n := 1
|
||||
mut b := &n
|
||||
*b = 10
|
||||
//mut b := mut a
|
||||
//b = 10
|
||||
var b := &n
|
||||
//
|
||||
(*b) = 10
|
||||
// mut b := mut a
|
||||
// b = 10
|
||||
}
|
||||
|
||||
fn test_mut_2() {
|
||||
zero := 0
|
||||
mut b := B{}
|
||||
var b := B{}
|
||||
b.a << A{}
|
||||
b.a[0].v = [9, 8, 7]
|
||||
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_in
|
||||
key_interface
|
||||
key_is
|
||||
// key_it
|
||||
key_match
|
||||
key_module
|
||||
|
@ -246,6 +247,7 @@ fn build_token_str() []string {
|
|||
s[Kind.key_select] = 'select'
|
||||
s[Kind.key_none] = 'none'
|
||||
s[Kind.key_offsetof] = '__offsetof'
|
||||
s[Kind.key_is] = 'is'
|
||||
s[Kind.key_var] = 'var'
|
||||
return s
|
||||
}
|
||||
|
@ -385,7 +387,7 @@ pub fn (tok Token) precedence() int {
|
|||
.left_shift_assign, .right_shift_assign, .mult_assign, .xor_assign {
|
||||
return int(Precedence.assign)
|
||||
}
|
||||
.key_in, .not_in, .key_as {
|
||||
.key_in, .not_in, .key_as, .key_is {
|
||||
return int(Precedence.in_as)
|
||||
}
|
||||
.logical_or, .and {
|
||||
|
@ -425,7 +427,7 @@ pub fn (k Kind) is_start_of_type() bool {
|
|||
pub fn (kind Kind) is_infix() bool {
|
||||
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]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue