v2: match cgen; use `as` for casting

pull/3673/head
Alexander Medvednikov 2020-02-07 14:49:14 +01:00
parent 27719ded9b
commit 9034b1fd08
14 changed files with 154 additions and 73 deletions

View File

@ -6,13 +6,13 @@ module builtin
#include <float.h> #include <float.h>
pub fn (d f64) str() string { pub fn (d f64) str() string {
buf := malloc(sizeof(double) * 5 + 1) // TODO buf := malloc(sizeof(double) * 5 + 1) // TODO
C.sprintf(charptr(buf), '%f', d) C.sprintf(buf as charptr, '%f', d)
return tos(buf, vstrlen(buf)) return tos(buf, vstrlen(buf))
} }
pub fn (d f32) str() string { pub fn (d f32) str() string {
buf := malloc(sizeof(double) * 5 + 1) // TODO buf := malloc(sizeof(double) * 5 + 1) // TODO
C.sprintf(charptr(buf), '%f', d) C.sprintf((buf), '%f', d)
return tos(buf, vstrlen(buf)) return tos(buf, vstrlen(buf))
} }
@ -20,7 +20,7 @@ pub fn (d f32) str() string {
pub fn (x f64) strsci(digit_num int) string { pub fn (x f64) strsci(digit_num int) string {
buf := malloc(digit_num * 2 + 2) // TODO buf := malloc(digit_num * 2 + 2) // TODO
conf_str := '%0.' + digit_num.str() + 'e' conf_str := '%0.' + digit_num.str() + 'e'
C.sprintf(charptr(buf), charptr(conf_str.str), x) C.sprintf((buf), (conf_str.str), x)
tmpstr := tos(buf, vstrlen(buf)) tmpstr := tos(buf, vstrlen(buf))
return tmpstr return tmpstr
} }
@ -28,7 +28,7 @@ pub fn (x f64) strsci(digit_num int) string {
// return a long string of the input f64, max // return a long string of the input f64, max
pub fn (x f64) strlong() string { pub fn (x f64) strlong() string {
buf := malloc(18 + 32) // TODO buf := malloc(18 + 32) // TODO
C.sprintf(charptr(buf), '%0.30lf', x) C.sprintf((buf), '%0.30lf', x)
tmpstr := tos(buf, vstrlen(buf)) tmpstr := tos(buf, vstrlen(buf))
return tmpstr return tmpstr
} }

View File

@ -5,7 +5,7 @@ module builtin
pub fn ptr_str(ptr voidptr) string { pub fn ptr_str(ptr voidptr) string {
buf := malloc(sizeof(double) * 5 + 1) // TODO buf := malloc(sizeof(double) * 5 + 1) // TODO
C.sprintf(charptr(buf), '%p', ptr) C.sprintf((buf), '%p', ptr)
return tos(buf, vstrlen(buf)) return tos(buf, vstrlen(buf))
} }
@ -28,7 +28,7 @@ pub fn (nn int) str() string {
// Fill the string from the end // Fill the string from the end
for n > 0 { for n > 0 {
d := n % 10 d := n % 10
buf[max - len - 1] = d + int(`0`) buf[max - len - 1] = d + `0` as int
len++ len++
n = n / 10 n = n / 10
} }
@ -42,31 +42,31 @@ pub fn (nn int) str() string {
} }
pub fn (n i8) str() string { pub fn (n i8) str() string {
return int(n).str() return (n as int).str()
} }
pub fn (n i16) str() string { pub fn (n i16) str() string {
return int(n).str() return (n as int).str()
} }
pub fn (n u16) str() string { pub fn (n u16) str() string {
return int(n).str() return (n as int).str()
} }
pub fn (nn u32) str() string { pub fn (nn u32) str() string {
mut n := nn mut n := nn
if n == u32(0) { if n == (0 as u32) {
return '0' return '0'
} }
max := 16 max := 16
mut buf := malloc(max) mut buf := malloc(max)
mut len := 0 mut len := 0
// Fill the string from the end // Fill the string from the end
for n > u32(0) { for n > (0 as u32) {
d := n % u32(10) d := n % (10 as u32)
buf[max - len - 1] = d + u32(`0`) buf[max - len - 1] = d + (`0` as u32)
len++ len++
n = n / u32(10) n = n / (10 as u32)
} }
return tos(buf + max - len, len) return tos(buf + max - len, len)
} }
@ -94,23 +94,24 @@ pub fn (nn byte) str() string {
pub fn (nn i64) str() string { pub fn (nn i64) str() string {
mut n := nn mut n := nn
if n == i64(0) { if n == (0 as i64) {
return '0' return '0'
} }
max := 32 max := 32
mut buf := malloc(max) mut buf := malloc(max)
mut len := 0 mut len := 0
mut is_neg := false mut is_neg := false
if n < i64(0) { if n < 0 { //(0 as i64) {
n = -n n = -n
is_neg = true is_neg = true
} }
// Fill the string from the end // Fill the string from the end
for n > i64(0) { for n > 0 {
d := int(n % i64(10)) //d := int(n % (10 as i64))
buf[max - len - 1] = d + int(`0`) d := n % 10
buf[max - len - 1] = d + `0` as int
len++ len++
n = n / i64(10) n /= 10
} }
// Prepend - if it's negative // Prepend - if it's negative
if is_neg { if is_neg {
@ -122,18 +123,18 @@ pub fn (nn i64) str() string {
pub fn (nn u64) str() string { pub fn (nn u64) str() string {
mut n := nn mut n := nn
if n == u64(0) { if n == 0 {
return '0' return '0'
} }
max := 32 max := 32
mut buf := malloc(max) mut buf := malloc(max)
mut len := 0 mut len := 0
// Fill the string from the end // Fill the string from the end
for n > u64(0) { for n > 0 {
d := n % u64(10) d := n % 10
buf[max - len - 1] = d + u64(`0`) buf[max - len - 1] = d + (`0` as u64)
len++ len++
n = n / u64(10) n = n / (10)
} }
return tos(buf + max - len, len) return tos(buf + max - len, len)
} }
@ -148,24 +149,24 @@ pub fn (b bool) str() string {
pub fn (n int) hex() string { pub fn (n int) hex() string {
len := if n >= 0 { n.str().len + 3 } else { 11 } len := if n >= 0 { n.str().len + 3 } else { 11 }
hex := malloc(len) // 0x + \n hex := malloc(len) // 0x + \n
count := C.sprintf(charptr(hex), '0x%x', n) count := C.sprintf((hex), '0x%x', n)
return tos(hex, count) return tos(hex, count)
} }
pub fn (n i64) hex() string { pub fn (n i64) hex() string {
len := if n >= i64(0) { n.str().len + 3 } else { 19 } len := if n >= 0 { n.str().len + 3 } else { 19 }
hex := malloc(len) hex := malloc(len)
// QTODO // QTODO
//count := C.sprintf(charptr(hex), '0x%'C.PRIx64, n) //count := C.sprintf(charptr(hex), '0x%'C.PRIx64, n)
count := C.sprintf(charptr(hex), '0x%x', n) count := C.sprintf(hex, '0x%x', n)
return tos(hex, count) return tos(hex, count)
} }
pub fn (n u64) hex() string { pub fn (n u64) hex() string {
len := if n >= u64(0) { n.str().len + 3 } else { 19 } len := if n >= 0 { n.str().len + 3 } else { 19 }
hex := malloc(len) hex := malloc(len)
//count := C.sprintf(charptr(hex), '0x%'C.PRIx64, n) //count := C.sprintf(charptr(hex), '0x%'C.PRIx64, n)
count := C.sprintf(charptr(hex), '0x%lx', n) count := C.sprintf((hex), '0x%lx', n)
return tos(hex, count) return tos(hex, count)
} }
@ -179,14 +180,14 @@ pub fn (a []byte) contains(val byte) bool {
} }
pub fn (c rune) str() string { pub fn (c rune) str() string {
fst_byte := int(c)>>8 * 3 & 0xff fst_byte := (c as int)>>8 * 3 & 0xff
len := utf8_char_len(fst_byte) len := utf8_char_len(fst_byte)
mut str := string{ mut str := string{
len: len len: len
str: malloc(len + 1) str: malloc(len + 1)
} }
for i := 0; i < len; i++ { for i := 0; i < len; i++ {
str.str[i] = int(c)>>8 * (3 - i) & 0xff str.str[i] = (c as int)>>8 * (3 - i) & 0xff
} }
str[len] = `\0` str[len] = `\0`
return str return str
@ -207,7 +208,7 @@ pub fn (c byte) is_capital() bool {
} }
pub fn (b []byte) clone() []byte { pub fn (b []byte) clone() []byte {
mut res := [byte(0)].repeat(b.len) mut res := [(0 as byte)].repeat(b.len)
for i := 0; i < b.len; i++ { for i := 0; i < b.len; i++ {
res[i] = b[i] res[i] = b[i]
} }

View File

@ -467,7 +467,7 @@ fn (p mut Parser) parse(pass Pass) {
} }
return return
} }
parsing_start_ticks := time.ticks() parsing_start_ticks := time.ticks()
compile_cycles_stuck_mask := u64( 0x1FFFFFFF ) // 2^29-1 cycles compile_cycles_stuck_mask := u64( 0x1FFFFFFF ) // 2^29-1 cycles
mut parsing_cycle := u64(1) mut parsing_cycle := u64(1)

View File

@ -77,6 +77,12 @@ fn (p mut Parser) bool_expression() string {
// `as` cast // `as` cast
// TODO remove copypasta // TODO remove copypasta
if p.tok == .key_as { if p.tok == .key_as {
return p.key_as(typ, start_ph)
}
return typ
}
fn (p mut Parser) key_as(typ string, start_ph int) string {
p.fspace() p.fspace()
p.next() p.next()
p.fspace() p.fspace()
@ -132,9 +138,7 @@ exit(1);
p.gen(')') p.gen(')')
} }
return cast_typ return cast_typ
} }
return typ
}
fn (p mut Parser) bterm() string { fn (p mut Parser) bterm() string {
ph := p.cgen.add_placeholder() ph := p.cgen.add_placeholder()

View File

@ -54,7 +54,7 @@ fn (p mut Parser) gen_fn_decl(f Fn, typ, str_args string) {
dll_export_linkage := if p.pref.ccompiler == 'msvc' && p.attr == 'live' && p.pref.is_so { '__declspec(dllexport) ' } else if p.attr == 'inline' { 'static inline ' } else { '' } dll_export_linkage := if p.pref.ccompiler == 'msvc' && p.attr == 'live' && p.pref.is_so { '__declspec(dllexport) ' } else if p.attr == 'inline' { 'static inline ' } else { '' }
fn_name_cgen := p.table.fn_gen_name(f) fn_name_cgen := p.table.fn_gen_name(f)
// str_args := f.str_args(p.table) // str_args := f.str_args(p.table)
if p.attr == 'live' && p.pref.is_so { if p.attr == 'live' && p.pref.is_so {
// See fn.v for details about impl_live_ functions // See fn.v for details about impl_live_ functions
p.genln('$typ impl_live_${fn_name_cgen} ($str_args);') p.genln('$typ impl_live_${fn_name_cgen} ($str_args);')
@ -549,6 +549,7 @@ fn (p mut Parser) gen_empty_map(typ string) {
} }
fn (p mut Parser) cast(typ string) { fn (p mut Parser) cast(typ string) {
//p.error('old cast syntax')
p.gen('(') p.gen('(')
defer { defer {
p.gen(')') p.gen(')')

View File

@ -25,7 +25,7 @@ struct MsvcResult {
type RegKey voidptr type RegKey voidptr
// Taken from the windows SDK // Taken from the windows SDK
const ( const (
HKEY_LOCAL_MACHINE = RegKey(0x80000002) HKEY_LOCAL_MACHINE = RegKey(0x80000002)// as RegKey
KEY_QUERY_VALUE = (0x0001) KEY_QUERY_VALUE = (0x0001)
KEY_WOW64_32KEY = (0x0200) KEY_WOW64_32KEY = (0x0200)
KEY_ENUMERATE_SUB_KEYS = (0x0008) KEY_ENUMERATE_SUB_KEYS = (0x0008)

View File

@ -94,7 +94,7 @@ const (
// f64 constants // f64 constants
// //
DIGITS = 18 DIGITS = 18
DOUBLE_PLUS_ZERO = u64(0x0000000000000000) DOUBLE_PLUS_ZERO = u64(0x0000000000000000)// as u64
DOUBLE_MINUS_ZERO = 0x8000000000000000 DOUBLE_MINUS_ZERO = 0x8000000000000000
DOUBLE_PLUS_INFINITY = 0x7FF0000000000000 DOUBLE_PLUS_INFINITY = 0x7FF0000000000000
DOUBLE_MINUS_INFINITY = 0xFFF0000000000000 DOUBLE_MINUS_INFINITY = 0xFFF0000000000000
@ -128,7 +128,7 @@ const (
MINUS = `-` MINUS = `-`
ZERO = `0` ZERO = `0`
NINE = `9` NINE = `9`
TEN = u32(10) TEN = 10// as u32
) )
/********************************************************************** /**********************************************************************
* *
@ -179,7 +179,7 @@ pub struct PrepNumber {
pub mut: pub mut:
negative bool=false // 0 if positive number, 1 if negative negative bool=false // 0 if positive number, 1 if negative
exponent int=0 // power of 10 exponent exponent int=0 // power of 10 exponent
mantissa u64=u64(0) // integer mantissa mantissa u64=0 as u64 // integer mantissa
} }
/********************************************************************** /**********************************************************************
* *

View File

@ -9,7 +9,7 @@ const (
// int_size = 32 << (~u32(0) >> 63) // int_size = 32 << (~u32(0) >> 63)
// max_u64 = u64(u64(1 << 63) - 1) // max_u64 = u64(u64(1 << 63) - 1)
int_size = 32 int_size = 32
max_u64 = u64(C.UINT64_MAX) // use this until we add support max_u64 = u64(C.UINT64_MAX)// as u64 // use this until we add support
) )
fn byte_to_lower(c byte) byte { fn byte_to_lower(c byte) byte {

View File

@ -12,7 +12,7 @@ const (
// The unsigned zero year for internal calculations. // The unsigned zero year for internal calculations.
// Must be 1 mod 400, and times before it will not compute correctly, // Must be 1 mod 400, and times before it will not compute correctly,
// but otherwise can be changed at will. // but otherwise can be changed at will.
absolute_zero_year = i64(-292277022399) absolute_zero_year = i64(-292277022399 )//as i64
seconds_per_minute = 60 seconds_per_minute = 60
seconds_per_hour = 60 * seconds_per_minute seconds_per_hour = 60 * seconds_per_minute
seconds_per_day = 24 * seconds_per_hour seconds_per_day = 24 * seconds_per_hour

View File

@ -20,7 +20,7 @@ HashStmt | AssignStmt
pub struct ExprStmt { pub struct ExprStmt {
pub: pub:
expr Expr expr Expr
typ table.TypeRef typ table.TypeRef
} }
pub struct IntegerLiteral { pub struct IntegerLiteral {
@ -184,6 +184,11 @@ mut:
typ table.TypeRef typ table.TypeRef
} }
pub struct StmtBlock {
pub:
stmts []Stmt
}
pub struct File { pub struct File {
pub: pub:
path string path string
@ -197,7 +202,7 @@ pub struct IdentVar {
pub mut: pub mut:
typ table.TypeRef typ table.TypeRef
is_mut bool is_mut bool
//name string // name string
} }
type IdentInfo = IdentVar type IdentInfo = IdentVar
@ -221,7 +226,7 @@ mut:
info IdentInfo info IdentInfo
} }
pub fn(i &Ident) var_info() IdentVar { pub fn (i &Ident) var_info() IdentVar {
match i.info { match i.info {
IdentVar { IdentVar {
return it return it
@ -255,6 +260,7 @@ pub:
} }
*/ */
pub struct PostfixExpr { pub struct PostfixExpr {
pub: pub:
op token.Kind op token.Kind
@ -290,13 +296,12 @@ pub:
pub struct MatchExpr { pub struct MatchExpr {
pub: pub:
tok_kind token.Kind tok_kind token.Kind
cond Expr cond Expr
stmts []Stmt blocks []StmtBlock
else_stmts []Stmt match_exprs []Expr
ti table.Type typ table.TypeRef
left Expr // `a` in `a := if ...` pos token.Position
pos token.Position
} }
pub struct CompIf { pub struct CompIf {
@ -340,7 +345,6 @@ pub:
name string name string
} }
pub struct AssignStmt { pub struct AssignStmt {
pub: pub:
left []Ident left []Ident
@ -348,7 +352,6 @@ pub:
op token.Kind op token.Kind
} }
// e.g. `[unsafe_fn]` // e.g. `[unsafe_fn]`
pub struct Attr { pub struct Attr {
pub: pub:
@ -368,7 +371,7 @@ pub:
pos token.Position pos token.Position
exprs []Expr exprs []Expr
mut: mut:
typ table.TypeRef typ table.TypeRef
} }
// s[10..20] // s[10..20]

View File

@ -42,6 +42,13 @@ pub fn (g mut Gen) writeln(s string) {
g.out.writeln(s) g.out.writeln(s)
} }
fn (g mut Gen) stmts(stmts []ast.Stmt) {
for stmt in stmts {
g.stmt(stmt)
g.writeln('')
}
}
fn (g mut Gen) stmt(node ast.Stmt) { fn (g mut Gen) stmt(node ast.Stmt) {
// println('cgen.stmt()') // println('cgen.stmt()')
// g.writeln('//// stmt start') // g.writeln('//// stmt start')
@ -110,18 +117,19 @@ fn (g mut Gen) stmt(node ast.Stmt) {
// ident0 := it.left[0] // ident0 := it.left[0]
// info0 := ident0.var_info() // info0 := ident0.var_info()
// for i, ident in it.left { // for i, ident in it.left {
// info := ident.var_info() // info := ident.var_info()
// if info0.typ.typ.kind == .multi_return { // if info0.typ.typ.kind == .multi_return {
// if i == 0 { // if i == 0 {
// g.write('$info.typ.typ.name $ident.name = ') // g.write('$info.typ.typ.name $ident.name = ')
// g.expr(it.right[0]) // g.expr(it.right[0])
// } else { // } else {
// arg_no := i-1 // arg_no := i-1
// g.write('$info.typ.typ.name $ident.name = $ident0.name->arg[$arg_no]') // g.write('$info.typ.typ.name $ident.name = $ident0.name->arg[$arg_no]')
// }
// }
// g.writeln(';')
// } // }
// }
// g.writeln(';')
// }
println('assign')
} }
ast.VarDecl { ast.VarDecl {
g.write('$it.typ.typ.name $it.name = ') g.write('$it.typ.typ.name $it.name = ')
@ -300,6 +308,23 @@ fn (g mut Gen) expr(node ast.Expr) {
g.writeln('}') g.writeln('}')
} }
} }
ast.MatchExpr {
mut tmp := ''
if it.typ.typ.kind != .void {
tmp = g.table.new_tmp_var()
}
g.write('$it.typ.typ.name $tmp = ')
g.expr(it.cond)
g.writeln(';') // $it.blocks.len')
for i, block in it.blocks {
match_expr := it.match_exprs[i]
g.write('if $tmp == ')
g.expr(match_expr)
g.writeln('{')
g.stmts(block.stmts)
g.writeln('}')
}
}
else { else {
println(term.red('cgen.expr(): bad node')) println(term.red('cgen.expr(): bad node'))
} }

View File

@ -6,6 +6,8 @@ void myuser();
multi_return_int_string multi_return(); multi_return_int_string multi_return();
void variadic(variadic_int a); void variadic(variadic_int a);
void ensure_cap(int required, int cap); void ensure_cap(int required, int cap);
void println(string s);
void matches();
int pi = 3; int pi = 3;
@ -97,3 +99,22 @@ void ensure_cap(int required, int cap) {
return; return;
} }
} }
void println(string s) {
}
void matches() {
int a = 100;
int tmp1 = a;
if tmp1 == 10{
println(tos3("10"));
}
if tmp1 == 20{
int k = a + 1;
}
;
}
}

View File

@ -106,6 +106,20 @@ fn ensure_cap(required int, cap int) {
} }
} }
fn println(s string){}
fn matches() {
a := 100
match a {
10 {
println('10')
}
20 {
k := a + 1
}
}
}
/* /*
const ( const (
path_sep = 10 path_sep = 10

View File

@ -1189,16 +1189,23 @@ fn (p mut Parser) global_decl() ast.GlobalDecl {
fn (p mut Parser) match_expr() (ast.Expr,table.TypeRef) { fn (p mut Parser) match_expr() (ast.Expr,table.TypeRef) {
p.check(.key_match) p.check(.key_match)
p.expr(0) cond,typ := p.expr(0)
p.check(.lcbr) p.check(.lcbr)
mut blocks := []ast.StmtBlock
mut match_exprs := []ast.Expr
for { for {
// p.tok.kind != .rcbr { // p.tok.kind != .rcbr {
p.expr(0) match_expr,_ := p.expr(0)
match_exprs << match_expr
p.warn('match block') p.warn('match block')
p.parse_block() blocks << ast.StmtBlock{
stmts: p.parse_block()
}
if p.tok.kind == .key_else { if p.tok.kind == .key_else {
p.next() p.next()
p.parse_block() blocks << ast.StmtBlock{
stmts: p.parse_block()
}
} }
if p.tok.kind == .rcbr { if p.tok.kind == .rcbr {
break break
@ -1206,7 +1213,12 @@ fn (p mut Parser) match_expr() (ast.Expr,table.TypeRef) {
} }
p.check(.rcbr) p.check(.rcbr)
mut node := ast.Expr{} mut node := ast.Expr{}
node = ast.MatchExpr{} node = ast.MatchExpr{
blocks: blocks
match_exprs: match_exprs
typ: typ
cond: cond
}
return node,p.table.type_ref(table.void_type_idx) return node,p.table.type_ref(table.void_type_idx)
} }