cgen: lots of fixes
parent
50ed4004f4
commit
843bb6dac1
|
@ -982,7 +982,7 @@ fn (p mut Parser) check_name() string {
|
||||||
|
|
||||||
fn (p mut Parser) check_string() string {
|
fn (p mut Parser) check_string() string {
|
||||||
s := p.lit
|
s := p.lit
|
||||||
p.check(.str)
|
p.check(.string)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1005,7 +1005,7 @@ fn (p &Parser) strtok() string {
|
||||||
}
|
}
|
||||||
return '`$p.lit`'
|
return '`$p.lit`'
|
||||||
}
|
}
|
||||||
if p.tok == .str {
|
if p.tok == .string{
|
||||||
if p.lit.contains("'") && !p.lit.contains('"') {
|
if p.lit.contains("'") && !p.lit.contains('"') {
|
||||||
return '"$p.lit"'
|
return '"$p.lit"'
|
||||||
}
|
}
|
||||||
|
@ -1296,7 +1296,7 @@ fn (p &Parser) print_tok() {
|
||||||
println(p.lit)
|
println(p.lit)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if p.tok == .str {
|
if p.tok == .string{
|
||||||
println('"$p.lit"')
|
println('"$p.lit"')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -2613,7 +2613,7 @@ fn (p mut Parser) map_init() string {
|
||||||
for {
|
for {
|
||||||
key := p.lit
|
key := p.lit
|
||||||
keys_gen += 'tos3("$key"), '
|
keys_gen += 'tos3("$key"), '
|
||||||
p.check(.str)
|
p.check(.string)
|
||||||
p.check(.colon)
|
p.check(.colon)
|
||||||
p.fspace()
|
p.fspace()
|
||||||
t,val_expr := p.tmp_expr()
|
t,val_expr := p.tmp_expr()
|
||||||
|
@ -2954,7 +2954,7 @@ fn (p mut Parser) return_st() {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Don't allow `return val` in functions that don't return anything
|
// Don't allow `return val` in functions that don't return anything
|
||||||
if p.tok == .name || p.tok == .number || p.tok == .str {
|
if p.tok == .name || p.tok == .number || p.tok == .string{
|
||||||
p.error_with_token_index('function `$p.cur_fn.name` should not return a value', p.cur_fn.fn_name_token_idx)
|
p.error_with_token_index('function `$p.cur_fn.name` should not return a value', p.cur_fn.fn_name_token_idx)
|
||||||
}
|
}
|
||||||
p.genln(deferred_text)
|
p.genln(deferred_text)
|
||||||
|
|
|
@ -11,7 +11,7 @@ fn (p mut Parser) inline_asm() {
|
||||||
p.check(.lcbr)
|
p.check(.lcbr)
|
||||||
s := p.check_string()
|
s := p.check_string()
|
||||||
p.genln('asm("$s"')
|
p.genln('asm("$s"')
|
||||||
for p.tok == .str {
|
for p.tok == .string{
|
||||||
p.genln('"$p.lit"')
|
p.genln('"$p.lit"')
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,12 +286,12 @@ fn (p mut Parser) name_expr() string {
|
||||||
name = p.generic_dispatch.inst[name]
|
name = p.generic_dispatch.inst[name]
|
||||||
}
|
}
|
||||||
// Raw string (`s := r'hello \n ')
|
// Raw string (`s := r'hello \n ')
|
||||||
if name == 'r' && p.peek() == .str && p.prev_tok != .str_dollar {
|
if name == 'r' && p.peek() == .string&& p.prev_tok != .str_dollar {
|
||||||
p.string_expr()
|
p.string_expr()
|
||||||
return 'string'
|
return 'string'
|
||||||
}
|
}
|
||||||
// C string (a zero terminated one) C.func( c'hello' )
|
// C string (a zero terminated one) C.func( c'hello' )
|
||||||
if name == 'c' && p.peek() == .str && p.prev_tok != .str_dollar {
|
if name == 'c' && p.peek() == .string&& p.prev_tok != .str_dollar {
|
||||||
p.string_expr()
|
p.string_expr()
|
||||||
return 'charptr'
|
return 'charptr'
|
||||||
}
|
}
|
||||||
|
@ -833,7 +833,7 @@ fn (p mut Parser) factor() string {
|
||||||
// TODO: make this work for arbitrary sumtype expressions, not just simple vars
|
// TODO: make this work for arbitrary sumtype expressions, not just simple vars
|
||||||
// NB: __SumTypeNames__[xxx][0] is the name of the sumtype itself;
|
// NB: __SumTypeNames__[xxx][0] is the name of the sumtype itself;
|
||||||
// idx>0 are the names of the sumtype children
|
// idx>0 are the names of the sumtype children
|
||||||
p.gen('tos3(__SumTypeNames__${type_of_var}[${vname}.typ])')
|
p.gen('tos3(__SumTypeNames__${type_of_var}[${vname}.typ])')
|
||||||
}else{
|
}else{
|
||||||
p.gen('tos3("$type_of_var")')
|
p.gen('tos3("$type_of_var")')
|
||||||
}
|
}
|
||||||
|
@ -913,7 +913,7 @@ fn (p mut Parser) factor() string {
|
||||||
typ = 'byte'
|
typ = 'byte'
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
.str {
|
.string{
|
||||||
p.string_expr()
|
p.string_expr()
|
||||||
typ = 'string'
|
typ = 'string'
|
||||||
return typ
|
return typ
|
||||||
|
@ -934,7 +934,7 @@ fn (p mut Parser) factor() string {
|
||||||
}
|
}
|
||||||
.lcbr {
|
.lcbr {
|
||||||
// `m := { 'one': 1 }`
|
// `m := { 'one': 1 }`
|
||||||
if p.peek() == .str {
|
if p.peek() == .string{
|
||||||
return p.map_init()
|
return p.map_init()
|
||||||
}
|
}
|
||||||
peek2 := p.tokens[p.token_idx + 1]
|
peek2 := p.tokens[p.token_idx + 1]
|
||||||
|
|
|
@ -1115,7 +1115,7 @@ fn (p mut Parser) fn_call_args(f mut Fn, generic_param_types []string) {
|
||||||
p.gen('/*YY f=$f.name arg=$arg.name is_moved=$arg.is_moved*/string_clone(')
|
p.gen('/*YY f=$f.name arg=$arg.name is_moved=$arg.is_moved*/string_clone(')
|
||||||
}
|
}
|
||||||
// x64 println gen
|
// x64 println gen
|
||||||
if p.pref.backend == .x64 && i == 0 && f.name == 'println' && p.tok == .str && p.peek() == .rpar {
|
if p.pref.backend == .x64 && i == 0 && f.name == 'println' && p.tok == .string&& p.peek() == .rpar {
|
||||||
//p.x64.gen_print(p.lit)
|
//p.x64.gen_print(p.lit)
|
||||||
}
|
}
|
||||||
mut typ := p.bool_expression()
|
mut typ := p.bool_expression()
|
||||||
|
|
|
@ -349,10 +349,10 @@ fn (s mut Scanner) scan() ScanRes {
|
||||||
if s.inter_end {
|
if s.inter_end {
|
||||||
if s.text[s.pos] == s.quote {
|
if s.text[s.pos] == s.quote {
|
||||||
s.inter_end = false
|
s.inter_end = false
|
||||||
return scan_res(.str, '')
|
return scan_res(.string, '')
|
||||||
}
|
}
|
||||||
s.inter_end = false
|
s.inter_end = false
|
||||||
return scan_res(.str, s.ident_string())
|
return scan_res(.string, s.ident_string())
|
||||||
}
|
}
|
||||||
s.skip_whitespace()
|
s.skip_whitespace()
|
||||||
// end of file
|
// end of file
|
||||||
|
@ -473,7 +473,7 @@ fn (s mut Scanner) scan() ScanRes {
|
||||||
return scan_res(.question, '')
|
return scan_res(.question, '')
|
||||||
}
|
}
|
||||||
single_quote, double_quote {
|
single_quote, double_quote {
|
||||||
return scan_res(.str, s.ident_string())
|
return scan_res(.string, s.ident_string())
|
||||||
}
|
}
|
||||||
`\`` {
|
`\`` {
|
||||||
// ` // apostrophe balance comment. do not remove
|
// ` // apostrophe balance comment. do not remove
|
||||||
|
@ -513,9 +513,9 @@ fn (s mut Scanner) scan() ScanRes {
|
||||||
s.pos++
|
s.pos++
|
||||||
if s.text[s.pos] == s.quote {
|
if s.text[s.pos] == s.quote {
|
||||||
s.inside_string = false
|
s.inside_string = false
|
||||||
return scan_res(.str, '')
|
return scan_res(.string, '')
|
||||||
}
|
}
|
||||||
return scan_res(.str, s.ident_string())
|
return scan_res(.string, s.ident_string())
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return scan_res(.rcbr, '')
|
return scan_res(.rcbr, '')
|
||||||
|
@ -558,19 +558,19 @@ fn (s mut Scanner) scan() ScanRes {
|
||||||
// println( 'file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @FN)
|
// println( 'file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @FN)
|
||||||
// ... which is useful while debugging/tracing
|
// ... which is useful while debugging/tracing
|
||||||
if name == 'FN' {
|
if name == 'FN' {
|
||||||
return scan_res(.str, s.fn_name)
|
return scan_res(.string, s.fn_name)
|
||||||
}
|
}
|
||||||
if name == 'FILE' {
|
if name == 'FILE' {
|
||||||
return scan_res(.str, cescaped_path(os.realpath(s.file_path)))
|
return scan_res(.string, cescaped_path(os.realpath(s.file_path)))
|
||||||
}
|
}
|
||||||
if name == 'LINE' {
|
if name == 'LINE' {
|
||||||
return scan_res(.str, (s.line_nr + 1).str())
|
return scan_res(.string, (s.line_nr + 1).str())
|
||||||
}
|
}
|
||||||
if name == 'COLUMN' {
|
if name == 'COLUMN' {
|
||||||
return scan_res(.str, (s.current_column()).str())
|
return scan_res(.string, (s.current_column()).str())
|
||||||
}
|
}
|
||||||
if name == 'VHASH' {
|
if name == 'VHASH' {
|
||||||
return scan_res(.str, vhash())
|
return scan_res(.string, vhash())
|
||||||
}
|
}
|
||||||
if !is_key(name) {
|
if !is_key(name) {
|
||||||
s.error('@ must be used before keywords (e.g. `@type string`)')
|
s.error('@ must be used before keywords (e.g. `@type string`)')
|
||||||
|
|
|
@ -52,7 +52,7 @@ fn (p mut Parser) string_expr() {
|
||||||
mut args := '"'
|
mut args := '"'
|
||||||
mut format := '"'
|
mut format := '"'
|
||||||
mut complex_inter := false // for vfmt
|
mut complex_inter := false // for vfmt
|
||||||
for p.tok == .str {
|
for p.tok == .string{
|
||||||
// Add the string between %d's
|
// Add the string between %d's
|
||||||
p.lit = p.lit.replace('%', '%%')
|
p.lit = p.lit.replace('%', '%%')
|
||||||
format += format_str(p.lit)
|
format += format_str(p.lit)
|
||||||
|
@ -64,7 +64,7 @@ fn (p mut Parser) string_expr() {
|
||||||
p.check(.str_dollar)
|
p.check(.str_dollar)
|
||||||
// If there's no string after current token, it means we are in
|
// If there's no string after current token, it means we are in
|
||||||
// a complex expression (`${...}`)
|
// a complex expression (`${...}`)
|
||||||
if p.peek() != .str {
|
if p.peek() != .string{
|
||||||
p.fgen('{')
|
p.fgen('{')
|
||||||
complex_inter = true
|
complex_inter = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -304,7 +304,7 @@ fn (p mut Parser) struct_decl(generic_param_types []string) {
|
||||||
.name {
|
.name {
|
||||||
val = p.check_name()
|
val = p.check_name()
|
||||||
}
|
}
|
||||||
.str {
|
.string{
|
||||||
val = p.check_string()
|
val = p.check_string()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -15,7 +15,7 @@ enum TokenKind {
|
||||||
eof
|
eof
|
||||||
name // user
|
name // user
|
||||||
number // 123
|
number // 123
|
||||||
str // 'foo'
|
string // 'foo'
|
||||||
str_inter // 'name=$user.name'
|
str_inter // 'name=$user.name'
|
||||||
chartoken // `A`
|
chartoken // `A`
|
||||||
plus
|
plus
|
||||||
|
@ -143,7 +143,7 @@ fn build_token_str() []string {
|
||||||
s[TokenKind.eof] = 'eof'
|
s[TokenKind.eof] = 'eof'
|
||||||
s[TokenKind.name] = 'name'
|
s[TokenKind.name] = 'name'
|
||||||
s[TokenKind.number] = 'number'
|
s[TokenKind.number] = 'number'
|
||||||
s[TokenKind.str] = 'STR'
|
s[TokenKind.string] = 'STR'
|
||||||
s[TokenKind.chartoken] = 'char'
|
s[TokenKind.chartoken] = 'char'
|
||||||
s[TokenKind.plus] = '+'
|
s[TokenKind.plus] = '+'
|
||||||
s[TokenKind.minus] = '-'
|
s[TokenKind.minus] = '-'
|
||||||
|
@ -292,7 +292,7 @@ pub fn (t Token) str() string {
|
||||||
if t.tok == .chartoken {
|
if t.tok == .chartoken {
|
||||||
return '`$t.lit`'
|
return '`$t.lit`'
|
||||||
}
|
}
|
||||||
if t.tok == .str {
|
if t.tok == .string {
|
||||||
return "'$t.lit'"
|
return "'$t.lit'"
|
||||||
}
|
}
|
||||||
if t.tok == .eof {
|
if t.tok == .eof {
|
||||||
|
|
|
@ -178,8 +178,8 @@ mut:
|
||||||
|
|
||||||
pub struct CallArg {
|
pub struct CallArg {
|
||||||
pub:
|
pub:
|
||||||
is_mut bool
|
is_mut bool
|
||||||
expr Expr
|
expr Expr
|
||||||
mut:
|
mut:
|
||||||
typ table.Type
|
typ table.Type
|
||||||
expected_type table.Type
|
expected_type table.Type
|
||||||
|
@ -437,8 +437,9 @@ pub struct EnumVal {
|
||||||
pub:
|
pub:
|
||||||
enum_name string
|
enum_name string
|
||||||
val string
|
val string
|
||||||
|
mod string // for full path `mod_Enum_val`
|
||||||
|
// typ table.Type
|
||||||
pos token.Position
|
pos token.Position
|
||||||
// name string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EnumDecl {
|
pub struct EnumDecl {
|
||||||
|
|
|
@ -132,6 +132,7 @@ pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type {
|
||||||
infix_expr.left_type = left_type
|
infix_expr.left_type = left_type
|
||||||
c.expected_type = left_type
|
c.expected_type = left_type
|
||||||
right_type := c.expr(infix_expr.right)
|
right_type := c.expr(infix_expr.right)
|
||||||
|
infix_expr.right_type = right_type
|
||||||
if !c.table.check(right_type, left_type) {
|
if !c.table.check(right_type, left_type) {
|
||||||
left := c.table.get_type_symbol(left_type)
|
left := c.table.get_type_symbol(left_type)
|
||||||
right := c.table.get_type_symbol(right_type)
|
right := c.table.get_type_symbol(right_type)
|
||||||
|
|
|
@ -63,7 +63,7 @@ pub fn (g mut Gen) typ(t table.Type) string {
|
||||||
if styp.starts_with('C__') {
|
if styp.starts_with('C__') {
|
||||||
styp = styp[3..]
|
styp = styp[3..]
|
||||||
}
|
}
|
||||||
if styp in ['stat', 'dirent*'] {
|
if styp in ['stat', 'dirent*', 'tm'] {
|
||||||
// TODO perf and other C structs
|
// TODO perf and other C structs
|
||||||
styp = 'struct $styp'
|
styp = 'struct $styp'
|
||||||
}
|
}
|
||||||
|
@ -106,9 +106,8 @@ pub fn (g mut Gen) write_typedef_types() {
|
||||||
styp := typ.name.replace('.', '__')
|
styp := typ.name.replace('.', '__')
|
||||||
g.definitions.writeln('typedef map $styp;')
|
g.definitions.writeln('typedef map $styp;')
|
||||||
}
|
}
|
||||||
.function {
|
// TODO:
|
||||||
// TODO:
|
.function {}
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -290,7 +289,10 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
ast.HashStmt {
|
ast.HashStmt {
|
||||||
// #include etc
|
// #include etc
|
||||||
g.definitions.writeln('#$it.val')
|
typ := it.val.all_before(' ')
|
||||||
|
if typ in ['#include', '#define'] {
|
||||||
|
g.definitions.writeln('#$it.val')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ast.Import {}
|
ast.Import {}
|
||||||
ast.Return {
|
ast.Return {
|
||||||
|
@ -466,7 +468,7 @@ fn (g mut Gen) fn_args(args []table.Arg, is_variadic bool) {
|
||||||
no_names := args.len > 0 && args[0].name == 'arg_1'
|
no_names := args.len > 0 && args[0].name == 'arg_1'
|
||||||
for i, arg in args {
|
for i, arg in args {
|
||||||
arg_type_sym := g.table.get_type_symbol(arg.typ)
|
arg_type_sym := g.table.get_type_symbol(arg.typ)
|
||||||
mut arg_type_name := arg_type_sym.name.replace('.', '__')
|
mut arg_type_name := g.typ(arg.typ) // arg_type_sym.name.replace('.', '__')
|
||||||
is_varg := i == args.len - 1 && is_variadic
|
is_varg := i == args.len - 1 && is_variadic
|
||||||
if is_varg {
|
if is_varg {
|
||||||
g.varaidic_args[int(arg.typ).str()] = 0
|
g.varaidic_args[int(arg.typ).str()] = 0
|
||||||
|
@ -486,14 +488,14 @@ fn (g mut Gen) fn_args(args []table.Arg, is_variadic bool) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mut nr_muls := table.type_nr_muls(arg.typ)
|
mut nr_muls := table.type_nr_muls(arg.typ)
|
||||||
mut s := arg_type_name + ' ' + arg.name
|
s := arg_type_name + ' ' + arg.name
|
||||||
if arg.is_mut {
|
if arg.is_mut {
|
||||||
// mut arg needs one *
|
// mut arg needs one *
|
||||||
nr_muls = 1
|
nr_muls = 1
|
||||||
}
|
}
|
||||||
if nr_muls > 0 && !is_varg {
|
// if nr_muls > 0 && !is_varg {
|
||||||
s = arg_type_name + strings.repeat(`*`, nr_muls) + ' ' + arg.name
|
// s = arg_type_name + strings.repeat(`*`, nr_muls) + ' ' + arg.name
|
||||||
}
|
// }
|
||||||
g.write(s)
|
g.write(s)
|
||||||
g.definitions.write(s)
|
g.definitions.write(s)
|
||||||
}
|
}
|
||||||
|
@ -625,6 +627,7 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
g.write("'$it.val'")
|
g.write("'$it.val'")
|
||||||
}
|
}
|
||||||
ast.EnumVal {
|
ast.EnumVal {
|
||||||
|
// g.write('/*EnumVal*/${it.mod}${it.enum_name}_$it.val')
|
||||||
g.write('${it.enum_name}_$it.val')
|
g.write('${it.enum_name}_$it.val')
|
||||||
}
|
}
|
||||||
ast.FloatLiteral {
|
ast.FloatLiteral {
|
||||||
|
@ -718,8 +721,16 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
}
|
}
|
||||||
g.write('if (')
|
g.write('if (')
|
||||||
for i, expr in branch.exprs {
|
for i, expr in branch.exprs {
|
||||||
g.write('$tmp == ')
|
if type_sym.kind == .string {
|
||||||
|
g.write('string_eq($tmp, ')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g.write('$tmp == ')
|
||||||
|
}
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
|
if type_sym.kind == .string {
|
||||||
|
g.write(')')
|
||||||
|
}
|
||||||
if i < branch.exprs.len - 1 {
|
if i < branch.exprs.len - 1 {
|
||||||
g.write(' || ')
|
g.write(' || ')
|
||||||
}
|
}
|
||||||
|
@ -948,16 +959,29 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) {
|
||||||
}
|
}
|
||||||
// arr << val
|
// arr << val
|
||||||
else if node.op == .left_shift && g.table.get_type_symbol(node.left_type).kind == .array {
|
else if node.op == .left_shift && g.table.get_type_symbol(node.left_type).kind == .array {
|
||||||
sym := g.table.get_type_symbol(node.left_type)
|
|
||||||
info := sym.info as table.Array
|
|
||||||
elem_type_str := g.typ(info.elem_type)
|
|
||||||
// g.write('array_push(&')
|
|
||||||
tmp := g.new_tmp_var()
|
tmp := g.new_tmp_var()
|
||||||
g.write('_PUSH(&')
|
sym := g.table.get_type_symbol(node.left_type)
|
||||||
g.expr(node.left)
|
right_sym := g.table.get_type_symbol(node.right_type)
|
||||||
g.write(', (')
|
if right_sym.kind == .array {
|
||||||
g.expr(node.right)
|
// push an array => PUSH_MANY
|
||||||
g.write('), $tmp, $elem_type_str)')
|
g.write('_PUSH_MANY(&')
|
||||||
|
g.expr(node.left)
|
||||||
|
g.write(', (')
|
||||||
|
g.expr(node.right)
|
||||||
|
styp := g.typ(node.left_type)
|
||||||
|
g.write('), $tmp, $styp)')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// push a single element
|
||||||
|
info := sym.info as table.Array
|
||||||
|
elem_type_str := g.typ(info.elem_type)
|
||||||
|
// g.write('array_push(&')
|
||||||
|
g.write('_PUSH(&')
|
||||||
|
g.expr(node.left)
|
||||||
|
g.write(', (')
|
||||||
|
g.expr(node.right)
|
||||||
|
g.write('), $tmp, $elem_type_str)')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// if node.op == .dot {
|
// if node.op == .dot {
|
||||||
|
@ -1156,16 +1180,16 @@ fn (g mut Gen) call_args(args []ast.CallArg) {
|
||||||
for i, arg in args {
|
for i, arg in args {
|
||||||
if table.type_is_variadic(arg.expected_type) {
|
if table.type_is_variadic(arg.expected_type) {
|
||||||
struct_name := 'varg_' + g.typ(arg.expected_type).replace('*', '_ptr')
|
struct_name := 'varg_' + g.typ(arg.expected_type).replace('*', '_ptr')
|
||||||
len := args.len-i
|
len := args.len - i
|
||||||
type_str := int(arg.expected_type).str()
|
type_str := int(arg.expected_type).str()
|
||||||
if len > g.varaidic_args[type_str] {
|
if len > g.varaidic_args[type_str] {
|
||||||
g.varaidic_args[type_str] = len
|
g.varaidic_args[type_str] = len
|
||||||
}
|
}
|
||||||
g.write('($struct_name){.len=$len,.args={')
|
g.write('($struct_name){.len=$len,.args={')
|
||||||
for j in i..args.len {
|
for j in i .. args.len {
|
||||||
g.ref_or_deref_arg(args[j])
|
g.ref_or_deref_arg(args[j])
|
||||||
g.expr(args[j].expr)
|
g.expr(args[j].expr)
|
||||||
if j < args.len-1 {
|
if j < args.len - 1 {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ const (
|
||||||
// c_headers
|
// c_headers
|
||||||
#include <stdio.h> // TODO remove all these includes, define all function signatures and types manually
|
#include <stdio.h> // TODO remove all these includes, define all function signatures and types manually
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
//#include "fns.h"
|
//#include "fns.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt {
|
||||||
pref: &pref.Preferences{}
|
pref: &pref.Preferences{}
|
||||||
scope: scope
|
scope: scope
|
||||||
// scope: &ast.Scope{start_pos: 0, parent: 0}
|
// scope: &ast.Scope{start_pos: 0, parent: 0}
|
||||||
|
|
||||||
}
|
}
|
||||||
p.init_parse_fns()
|
p.init_parse_fns()
|
||||||
p.read_first_token()
|
p.read_first_token()
|
||||||
|
@ -72,7 +72,7 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment
|
||||||
parent: 0
|
parent: 0
|
||||||
}
|
}
|
||||||
// comments_mode: comments_mode
|
// comments_mode: comments_mode
|
||||||
|
|
||||||
}
|
}
|
||||||
p.read_first_token()
|
p.read_first_token()
|
||||||
// p.scope = &ast.Scope{start_pos: p.tok.position(), parent: 0}
|
// p.scope = &ast.Scope{start_pos: p.tok.position(), parent: 0}
|
||||||
|
@ -610,9 +610,10 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
||||||
p.expr_mod = ''
|
p.expr_mod = ''
|
||||||
return ast.EnumVal{
|
return ast.EnumVal{
|
||||||
enum_name: enum_name // lp.prepend_mod(enum_name)
|
enum_name: enum_name // lp.prepend_mod(enum_name)
|
||||||
|
|
||||||
val: val
|
val: val
|
||||||
pos: p.tok.position()
|
pos: p.tok.position()
|
||||||
|
mod: mod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -633,7 +634,7 @@ pub fn (p mut Parser) expr(precedence int) ast.Expr {
|
||||||
.name {
|
.name {
|
||||||
node = p.name_expr()
|
node = p.name_expr()
|
||||||
}
|
}
|
||||||
.str {
|
.string {
|
||||||
node = p.string_expr()
|
node = p.string_expr()
|
||||||
}
|
}
|
||||||
.dot {
|
.dot {
|
||||||
|
@ -702,7 +703,7 @@ pub fn (p mut Parser) expr(precedence int) ast.Expr {
|
||||||
// Map `{"age": 20}` or `{ x | foo:bar, a:10 }`
|
// Map `{"age": 20}` or `{ x | foo:bar, a:10 }`
|
||||||
.lcbr {
|
.lcbr {
|
||||||
p.next()
|
p.next()
|
||||||
if p.tok.kind == .str {
|
if p.tok.kind == .string{
|
||||||
mut keys := []ast.Expr
|
mut keys := []ast.Expr
|
||||||
mut vals := []ast.Expr
|
mut vals := []ast.Expr
|
||||||
for p.tok.kind != .rcbr && p.tok.kind != .eof {
|
for p.tok.kind != .rcbr && p.tok.kind != .eof {
|
||||||
|
@ -940,7 +941,7 @@ fn (p mut Parser) infix_expr(left ast.Expr) ast.Expr {
|
||||||
left: left
|
left: left
|
||||||
right: right
|
right: right
|
||||||
// right_type: typ
|
// right_type: typ
|
||||||
|
|
||||||
op: op
|
op: op
|
||||||
pos: pos
|
pos: pos
|
||||||
}
|
}
|
||||||
|
@ -1054,7 +1055,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
||||||
p.scope.register_var(ast.Var{
|
p.scope.register_var(ast.Var{
|
||||||
name: var_name
|
name: var_name
|
||||||
// expr: cond
|
// expr: cond
|
||||||
|
|
||||||
})
|
})
|
||||||
stmts := p.parse_block()
|
stmts := p.parse_block()
|
||||||
// println('nr stmts=$stmts.len')
|
// println('nr stmts=$stmts.len')
|
||||||
|
@ -1149,11 +1150,11 @@ fn (p mut Parser) if_expr() ast.Expr {
|
||||||
stmts: stmts
|
stmts: stmts
|
||||||
else_stmts: else_stmts
|
else_stmts: else_stmts
|
||||||
// typ: typ
|
// typ: typ
|
||||||
|
|
||||||
pos: pos
|
pos: pos
|
||||||
has_else: has_else
|
has_else: has_else
|
||||||
// left: left
|
// left: left
|
||||||
|
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
@ -1168,7 +1169,7 @@ fn (p mut Parser) string_expr() ast.Expr {
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
// Handle $ interpolation
|
// Handle $ interpolation
|
||||||
for p.tok.kind == .str {
|
for p.tok.kind == .string{
|
||||||
p.next()
|
p.next()
|
||||||
if p.tok.kind != .str_dollar {
|
if p.tok.kind != .str_dollar {
|
||||||
continue
|
continue
|
||||||
|
@ -1328,7 +1329,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl {
|
||||||
fields << ast.Field{
|
fields << ast.Field{
|
||||||
name: name
|
name: name
|
||||||
// typ: typ
|
// typ: typ
|
||||||
|
|
||||||
}
|
}
|
||||||
exprs << expr
|
exprs << expr
|
||||||
// TODO: once consts are fixed reg here & update in checker
|
// TODO: once consts are fixed reg here & update in checker
|
||||||
|
|
|
@ -359,10 +359,10 @@ pub fn (s mut Scanner) scan() token.Token {
|
||||||
if s.inter_end {
|
if s.inter_end {
|
||||||
if s.text[s.pos] == s.quote {
|
if s.text[s.pos] == s.quote {
|
||||||
s.inter_end = false
|
s.inter_end = false
|
||||||
return s.scan_res(.str, '')
|
return s.scan_res(.string, '')
|
||||||
}
|
}
|
||||||
s.inter_end = false
|
s.inter_end = false
|
||||||
return s.scan_res(.str, s.ident_string())
|
return s.scan_res(.string, s.ident_string())
|
||||||
}
|
}
|
||||||
s.skip_whitespace()
|
s.skip_whitespace()
|
||||||
// end of file
|
// end of file
|
||||||
|
@ -483,7 +483,7 @@ pub fn (s mut Scanner) scan() token.Token {
|
||||||
return s.scan_res(.question, '')
|
return s.scan_res(.question, '')
|
||||||
}
|
}
|
||||||
single_quote, double_quote {
|
single_quote, double_quote {
|
||||||
return s.scan_res(.str, s.ident_string())
|
return s.scan_res(.string, s.ident_string())
|
||||||
}
|
}
|
||||||
`\`` {
|
`\`` {
|
||||||
// ` // apostrophe balance comment. do not remove
|
// ` // apostrophe balance comment. do not remove
|
||||||
|
@ -523,9 +523,9 @@ pub fn (s mut Scanner) scan() token.Token {
|
||||||
s.pos++
|
s.pos++
|
||||||
if s.text[s.pos] == s.quote {
|
if s.text[s.pos] == s.quote {
|
||||||
s.inside_string = false
|
s.inside_string = false
|
||||||
return s.scan_res(.str, '')
|
return s.scan_res(.string, '')
|
||||||
}
|
}
|
||||||
return s.scan_res(.str, s.ident_string())
|
return s.scan_res(.string, s.ident_string())
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return s.scan_res(.rcbr, '')
|
return s.scan_res(.rcbr, '')
|
||||||
|
@ -568,19 +568,19 @@ pub fn (s mut Scanner) scan() token.Token {
|
||||||
// println( 'file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @FN)
|
// println( 'file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @FN)
|
||||||
// ... which is useful while debugging/tracing
|
// ... which is useful while debugging/tracing
|
||||||
if name == 'FN' {
|
if name == 'FN' {
|
||||||
return s.scan_res(.str, s.fn_name)
|
return s.scan_res(.string, s.fn_name)
|
||||||
}
|
}
|
||||||
if name == 'FILE' {
|
if name == 'FILE' {
|
||||||
return s.scan_res(.str, cescaped_path(os.realpath(s.file_path)))
|
return s.scan_res(.string, cescaped_path(os.realpath(s.file_path)))
|
||||||
}
|
}
|
||||||
if name == 'LINE' {
|
if name == 'LINE' {
|
||||||
return s.scan_res(.str, (s.line_nr + 1).str())
|
return s.scan_res(.string, (s.line_nr + 1).str())
|
||||||
}
|
}
|
||||||
if name == 'COLUMN' {
|
if name == 'COLUMN' {
|
||||||
return s.scan_res(.str, (s.current_column()).str())
|
return s.scan_res(.string, (s.current_column()).str())
|
||||||
}
|
}
|
||||||
if name == 'VHASH' {
|
if name == 'VHASH' {
|
||||||
return s.scan_res(.str, vhash())
|
return s.scan_res(.string, vhash())
|
||||||
}
|
}
|
||||||
if !token.is_key(name) {
|
if !token.is_key(name) {
|
||||||
s.error('@ must be used before keywords (e.g. `@type string`)')
|
s.error('@ must be used before keywords (e.g. `@type string`)')
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub enum Kind {
|
||||||
eof
|
eof
|
||||||
name // user
|
name // user
|
||||||
number // 123
|
number // 123
|
||||||
str // 'foo'
|
string // 'foo'
|
||||||
str_inter // 'name=$user.name'
|
str_inter // 'name=$user.name'
|
||||||
chartoken // `A`
|
chartoken // `A`
|
||||||
plus
|
plus
|
||||||
|
@ -148,7 +148,7 @@ fn build_token_str() []string {
|
||||||
s[Kind.eof] = 'eof'
|
s[Kind.eof] = 'eof'
|
||||||
s[Kind.name] = 'name'
|
s[Kind.name] = 'name'
|
||||||
s[Kind.number] = 'number'
|
s[Kind.number] = 'number'
|
||||||
s[Kind.str] = 'STR'
|
s[Kind.string] = 'STR'
|
||||||
s[Kind.chartoken] = 'char'
|
s[Kind.chartoken] = 'char'
|
||||||
s[Kind.plus] = '+'
|
s[Kind.plus] = '+'
|
||||||
s[Kind.minus] = '-'
|
s[Kind.minus] = '-'
|
||||||
|
@ -287,7 +287,7 @@ pub fn (t Kind) str() string {
|
||||||
if t == .chartoken {
|
if t == .chartoken {
|
||||||
return 'char' // '`lit`'
|
return 'char' // '`lit`'
|
||||||
}
|
}
|
||||||
if t == .str {
|
if t == .string {
|
||||||
return 'str' // "'lit'"
|
return 'str' // "'lit'"
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -417,7 +417,7 @@ pub fn (tok Token) precedence() int {
|
||||||
|
|
||||||
// is_scalar returns true if the token is a scalar
|
// is_scalar returns true if the token is a scalar
|
||||||
pub fn (tok Token) is_scalar() bool {
|
pub fn (tok Token) is_scalar() bool {
|
||||||
return tok.kind in [.number, .str]
|
return tok.kind in [.number, .string]
|
||||||
}
|
}
|
||||||
|
|
||||||
// is_unary returns true if the token can be in a unary expression
|
// is_unary returns true if the token can be in a unary expression
|
||||||
|
|
Loading…
Reference in New Issue