cgen: fix string args in C calls; lower case consts in atof; fix struct types

pull/3947/head
Alexander Medvednikov 2020-03-07 01:05:19 +01:00
parent 968e310793
commit 58fb055763
2 changed files with 58 additions and 52 deletions

View File

@ -108,24 +108,24 @@ const (
// //
// parser state machine states // parser state machine states
// //
FSM_A = 0 fsm_a = 0
FSM_B = 1 fsm_b = 1
FSM_C = 2 fsm_c = 2
FSM_D = 3 fsm_d = 3
FSM_E = 4 fsm_e = 4
FSM_F = 5 fsm_f = 5
FSM_G = 6 fsm_g = 6
FSM_H = 7 fsm_h = 7
FSM_I = 8 fsm_i = 8
FSM_STOP = 9 FSM_STOP = 9
// //
// Possible parser return values. // Possible parser return values.
// //
PARSER_OK = 0 // parser finished OK parser_ok = 0 // parser finished OK
PARSER_PZERO = 1 // no digits or number is smaller than +-2^-1022 parser_pzero = 1 // no digits or number is smaller than +-2^-1022
PARSER_MZERO = 2 // number is negative, module smaller parser_mzero = 2 // number is negative, module smaller
PARSER_PINF = 3 // number is higher than +HUGE_VAL parser_pinf = 3 // number is higher than +HUGE_VAL
PARSER_MINF = 4 // number is lower than -HUGE_VAL parser_minf = 4 // number is lower than -HUGE_VAL
// //
// char constants // char constants
// Note: Modify these if working with non-ASCII encoding // Note: Modify these if working with non-ASCII encoding
@ -178,10 +178,10 @@ pub mut:
// parser return a support struct with all the parsing information for the converter // parser return a support struct with all the parsing information for the converter
fn parser(s string) (int,PrepNumber) { fn parser(s string) (int,PrepNumber) {
mut state := FSM_A mut state := fsm_a
mut digx := 0 mut digx := 0
mut c := ` ` // initial value for kicking off the state machine mut c := ` ` // initial value for kicking off the state machine
mut result := PARSER_OK mut result := parser_ok
mut expneg := false mut expneg := false
mut expexp := 0 mut expexp := 0
mut i := 0 mut i := 0
@ -190,17 +190,17 @@ fn parser(s string) (int,PrepNumber) {
for state != FSM_STOP { for state != FSM_STOP {
match state { match state {
// skip starting spaces // skip starting spaces
FSM_A { fsm_a {
if is_space(c) == true { if is_space(c) == true {
c = s[i++] c = s[i++]
} }
else { else {
state = FSM_B state = fsm_b
} }
} }
// check for the sign or point // check for the sign or point
FSM_B { fsm_b {
state = FSM_C state = fsm_c
if c == PLUS { if c == PLUS {
c = s[i++] c = s[i++]
//i++ //i++
@ -218,20 +218,20 @@ fn parser(s string) (int,PrepNumber) {
} }
} }
// skip the inital zeros // skip the inital zeros
FSM_C { fsm_c {
if c == ZERO { if c == ZERO {
c = s[i++] c = s[i++]
} }
else if c == DPOINT { else if c == DPOINT {
c = s[i++] c = s[i++]
state = FSM_D state = fsm_d
} }
else { else {
state = FSM_E state = fsm_e
} }
} }
// reading leading zeros in the fractional part of mantissa // reading leading zeros in the fractional part of mantissa
FSM_D { fsm_d {
if c == ZERO { if c == ZERO {
c = s[i++] c = s[i++]
if pn.exponent > -2147483647 { if pn.exponent > -2147483647 {
@ -239,11 +239,11 @@ fn parser(s string) (int,PrepNumber) {
} }
} }
else { else {
state = FSM_F state = fsm_f
} }
} }
// reading integer part of mantissa // reading integer part of mantissa
FSM_E { fsm_e {
if is_digit(c) { if is_digit(c) {
if digx < DIGITS { if digx < DIGITS {
pn.mantissa *= 10 pn.mantissa *= 10
@ -257,14 +257,14 @@ fn parser(s string) (int,PrepNumber) {
} }
else if c == DPOINT { else if c == DPOINT {
c = s[i++] c = s[i++]
state = FSM_F state = fsm_f
} }
else { else {
state = FSM_F state = fsm_f
} }
} }
// reading fractional part of mantissa // reading fractional part of mantissa
FSM_F { fsm_f {
if is_digit(c) { if is_digit(c) {
if digx < DIGITS { if digx < DIGITS {
pn.mantissa *= 10 pn.mantissa *= 10
@ -276,14 +276,14 @@ fn parser(s string) (int,PrepNumber) {
} }
else if is_exp(c) { else if is_exp(c) {
c = s[i++] c = s[i++]
state = FSM_G state = fsm_g
} }
else { else {
state = FSM_G state = fsm_g
} }
} }
// reading sign of exponent // reading sign of exponent
FSM_G { fsm_g {
if c == PLUS { if c == PLUS {
c = s[i++] c = s[i++]
} }
@ -291,19 +291,19 @@ fn parser(s string) (int,PrepNumber) {
expneg = true expneg = true
c = s[i++] c = s[i++]
} }
state = FSM_H state = fsm_h
} }
// skipping leading zeros of exponent // skipping leading zeros of exponent
FSM_H { fsm_h {
if c == ZERO { if c == ZERO {
c = s[i++] c = s[i++]
} }
else { else {
state = FSM_I state = fsm_i
} }
} }
// reading exponent digits // reading exponent digits
FSM_I { fsm_i {
if is_digit(c) { if is_digit(c) {
if expexp < 214748364 { if expexp < 214748364 {
expexp *= 10 expexp *= 10
@ -328,26 +328,26 @@ fn parser(s string) (int,PrepNumber) {
pn.exponent += expexp pn.exponent += expexp
if pn.mantissa == 0 { if pn.mantissa == 0 {
if pn.negative { if pn.negative {
result = PARSER_MZERO result = parser_mzero
} }
else { else {
result = PARSER_PZERO result = parser_pzero
} }
} }
else if (pn.exponent > 309) { else if (pn.exponent > 309) {
if pn.negative { if pn.negative {
result = PARSER_MINF result = parser_minf
} }
else { else {
result = PARSER_PINF result = parser_pinf
} }
} }
else if pn.exponent < -328 { else if pn.exponent < -328 {
if pn.negative { if pn.negative {
result = PARSER_MZERO result = parser_mzero
} }
else { else {
result = PARSER_PZERO result = parser_pzero
} }
} }
return result,pn return result,pn
@ -538,19 +538,19 @@ pub fn atof64(s string) f64 {
res_parsing,pn = parser(s + ' ') // TODO: need an extra char for now res_parsing,pn = parser(s + ' ') // TODO: need an extra char for now
// println(pn) // println(pn)
match res_parsing { match res_parsing {
PARSER_OK { parser_ok {
res.u = converter(mut pn) res.u = converter(mut pn)
} }
PARSER_PZERO { parser_pzero {
res.u = DOUBLE_PLUS_ZERO res.u = DOUBLE_PLUS_ZERO
} }
PARSER_MZERO { parser_mzero {
res.u = DOUBLE_MINUS_ZERO res.u = DOUBLE_MINUS_ZERO
} }
PARSER_PINF { parser_pinf {
res.u = DOUBLE_PLUS_INFINITY res.u = DOUBLE_PLUS_INFINITY
} }
PARSER_MINF { parser_minf {
res.u = DOUBLE_MINUS_INFINITY res.u = DOUBLE_MINUS_INFINITY
} }
else { else {

View File

@ -16,6 +16,7 @@ struct Gen {
mut: mut:
fn_decl &ast.FnDecl // pointer to the FnDecl we are currently inside otherwise 0 fn_decl &ast.FnDecl // pointer to the FnDecl we are currently inside otherwise 0
tmp_count int tmp_count int
is_c_call bool // e.g. `C.printf("v")`
} }
pub fn cgen(files []ast.File, table &table.Table) string { pub fn cgen(files []ast.File, table &table.Table) string {
@ -86,8 +87,7 @@ pub fn (g mut Gen) write_multi_return_types() {
// TODO copy pasta StructDecl // TODO copy pasta StructDecl
// for field in struct_info.fields { // for field in struct_info.fields {
for i, mr_typ in info.types { for i, mr_typ in info.types {
field_type_sym := g.table.get_type_symbol(mr_typ) type_name := g.typ(mr_typ)
type_name := field_type_sym.name.replace('.', '__')
g.definitions.writeln('\t$type_name arg${i};') g.definitions.writeln('\t$type_name arg${i};')
} }
g.definitions.writeln('} $name;\n') g.definitions.writeln('} $name;\n')
@ -388,11 +388,13 @@ fn (g mut Gen) expr(node ast.Expr) {
mut name := it.name.replace('.', '__') mut name := it.name.replace('.', '__')
if it.is_c { if it.is_c {
// Skip "C__" // Skip "C__"
g.is_c_call = true
name = name[3..] name = name[3..]
} }
g.write('${name}(') g.write('${name}(')
g.call_args(it.args) g.call_args(it.args)
g.write(')') g.write(')')
g.is_c_call = false
/* /*
for i, expr in it.args { for i, expr in it.args {
g.expr(expr) g.expr(expr)
@ -587,8 +589,13 @@ fn (g mut Gen) expr(node ast.Expr) {
g.write('sizeof($it.type_name)') g.write('sizeof($it.type_name)')
} }
ast.StringLiteral { ast.StringLiteral {
if g.is_c_call {
g.write('"$it.val"')
}
else {
g.write('tos3("$it.val")') g.write('tos3("$it.val")')
} }
}
// `user := User{name: 'Bob'}` // `user := User{name: 'Bob'}`
ast.StructInit { ast.StructInit {
styp := g.typ(it.typ) styp := g.typ(it.typ)
@ -744,8 +751,7 @@ fn (g mut Gen) write_types(types []table.TypeSymbol) {
// g.definitions.writeln('typedef struct {') // g.definitions.writeln('typedef struct {')
g.definitions.writeln('struct $name {') g.definitions.writeln('struct $name {')
for field in info.fields { for field in info.fields {
field_type_sym := g.table.get_type_symbol(field.typ) type_name := g.typ(field.typ)
type_name := field_type_sym.name.replace('.', '__')
g.definitions.writeln('\t$type_name $field.name;') g.definitions.writeln('\t$type_name $field.name;')
} }
// g.definitions.writeln('} $name;\n') // g.definitions.writeln('} $name;\n')