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

View File

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