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>
pub fn (d f64) str() string {
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))
}
pub fn (d f32) str() string {
buf := malloc(sizeof(double) * 5 + 1) // TODO
C.sprintf(charptr(buf), '%f', d)
C.sprintf((buf), '%f', d)
return tos(buf, vstrlen(buf))
}
@ -20,7 +20,7 @@ pub fn (d f32) str() string {
pub fn (x f64) strsci(digit_num int) string {
buf := malloc(digit_num * 2 + 2) // TODO
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))
return tmpstr
}
@ -28,7 +28,7 @@ pub fn (x f64) strsci(digit_num int) string {
// return a long string of the input f64, max
pub fn (x f64) strlong() string {
buf := malloc(18 + 32) // TODO
C.sprintf(charptr(buf), '%0.30lf', x)
C.sprintf((buf), '%0.30lf', x)
tmpstr := tos(buf, vstrlen(buf))
return tmpstr
}

View File

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

View File

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

View File

@ -77,6 +77,12 @@ fn (p mut Parser) bool_expression() string {
// `as` cast
// TODO remove copypasta
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.next()
p.fspace()
@ -132,9 +138,7 @@ exit(1);
p.gen(')')
}
return cast_typ
}
return typ
}
}
fn (p mut Parser) bterm() string {
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 { '' }
fn_name_cgen := p.table.fn_gen_name(f)
// str_args := f.str_args(p.table)
if p.attr == 'live' && p.pref.is_so {
// See fn.v for details about impl_live_ functions
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) {
//p.error('old cast syntax')
p.gen('(')
defer {
p.gen(')')

View File

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

View File

@ -94,7 +94,7 @@ const (
// f64 constants
//
DIGITS = 18
DOUBLE_PLUS_ZERO = u64(0x0000000000000000)
DOUBLE_PLUS_ZERO = u64(0x0000000000000000)// as u64
DOUBLE_MINUS_ZERO = 0x8000000000000000
DOUBLE_PLUS_INFINITY = 0x7FF0000000000000
DOUBLE_MINUS_INFINITY = 0xFFF0000000000000
@ -128,7 +128,7 @@ const (
MINUS = `-`
ZERO = `0`
NINE = `9`
TEN = u32(10)
TEN = 10// as u32
)
/**********************************************************************
*
@ -179,7 +179,7 @@ pub struct PrepNumber {
pub mut:
negative bool=false // 0 if positive number, 1 if negative
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)
// max_u64 = u64(u64(1 << 63) - 1)
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 {

View File

@ -12,7 +12,7 @@ const (
// The unsigned zero year for internal calculations.
// Must be 1 mod 400, and times before it will not compute correctly,
// 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_hour = 60 * seconds_per_minute
seconds_per_day = 24 * seconds_per_hour

View File

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

View File

@ -42,6 +42,13 @@ pub fn (g mut Gen) writeln(s string) {
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) {
// println('cgen.stmt()')
// g.writeln('//// stmt start')
@ -110,18 +117,19 @@ fn (g mut Gen) stmt(node ast.Stmt) {
// ident0 := it.left[0]
// info0 := ident0.var_info()
// for i, ident in it.left {
// info := ident.var_info()
// if info0.typ.typ.kind == .multi_return {
// if i == 0 {
// g.write('$info.typ.typ.name $ident.name = ')
// g.expr(it.right[0])
// } else {
// arg_no := i-1
// g.write('$info.typ.typ.name $ident.name = $ident0.name->arg[$arg_no]')
// }
// }
// g.writeln(';')
// info := ident.var_info()
// if info0.typ.typ.kind == .multi_return {
// if i == 0 {
// g.write('$info.typ.typ.name $ident.name = ')
// g.expr(it.right[0])
// } else {
// arg_no := i-1
// g.write('$info.typ.typ.name $ident.name = $ident0.name->arg[$arg_no]')
// }
// }
// g.writeln(';')
// }
println('assign')
}
ast.VarDecl {
g.write('$it.typ.typ.name $it.name = ')
@ -300,6 +308,23 @@ fn (g mut Gen) expr(node ast.Expr) {
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 {
println(term.red('cgen.expr(): bad node'))
}

View File

@ -6,6 +6,8 @@ void myuser();
multi_return_int_string multi_return();
void variadic(variadic_int a);
void ensure_cap(int required, int cap);
void println(string s);
void matches();
int pi = 3;
@ -97,3 +99,22 @@ void ensure_cap(int required, int cap) {
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 (
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) {
p.check(.key_match)
p.expr(0)
cond,typ := p.expr(0)
p.check(.lcbr)
mut blocks := []ast.StmtBlock
mut match_exprs := []ast.Expr
for {
// p.tok.kind != .rcbr {
p.expr(0)
match_expr,_ := p.expr(0)
match_exprs << match_expr
p.warn('match block')
p.parse_block()
blocks << ast.StmtBlock{
stmts: p.parse_block()
}
if p.tok.kind == .key_else {
p.next()
p.parse_block()
blocks << ast.StmtBlock{
stmts: p.parse_block()
}
}
if p.tok.kind == .rcbr {
break
@ -1206,7 +1213,12 @@ fn (p mut Parser) match_expr() (ast.Expr,table.TypeRef) {
}
p.check(.rcbr)
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)
}