cgen: multi return structs + other fixes
							parent
							
								
									cd8a5d1f2e
								
							
						
					
					
						commit
						136aa763a3
					
				| 
						 | 
					@ -36,14 +36,25 @@ pub fn new_builder(pref &pref.Preferences) Builder {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn (b mut Builder) gen_c(v_files []string) string {
 | 
					pub fn (b mut Builder) gen_c(v_files []string) string {
 | 
				
			||||||
 | 
						t0 := time.ticks()
 | 
				
			||||||
	b.parsed_files = parser.parse_files(v_files, b.table)
 | 
						b.parsed_files = parser.parse_files(v_files, b.table)
 | 
				
			||||||
	b.parse_imports()
 | 
						b.parse_imports()
 | 
				
			||||||
 | 
						t1 := time.ticks()
 | 
				
			||||||
 | 
						parse_time := t1 - t0
 | 
				
			||||||
 | 
						println('PARSE: ${parse_time}ms')
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
	b.checker.check_files(b.parsed_files)
 | 
						b.checker.check_files(b.parsed_files)
 | 
				
			||||||
 | 
						t2 := time.ticks()
 | 
				
			||||||
 | 
						check_time := t2 - t1
 | 
				
			||||||
 | 
						println('CHECK: ${check_time}ms')
 | 
				
			||||||
	if b.checker.nr_errors > 0 {
 | 
						if b.checker.nr_errors > 0 {
 | 
				
			||||||
		exit(1)
 | 
							exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// println('starting cgen...')
 | 
						// println('starting cgen...')
 | 
				
			||||||
	res := gen.cgen(b.parsed_files, b.table)
 | 
						res := gen.cgen(b.parsed_files, b.table)
 | 
				
			||||||
 | 
						t3 := time.ticks()
 | 
				
			||||||
 | 
						gen_time := t3 - t2
 | 
				
			||||||
 | 
						println('C GEN: ${gen_time}ms')
 | 
				
			||||||
	println('cgen done')
 | 
						println('cgen done')
 | 
				
			||||||
	// println(res)
 | 
						// println(res)
 | 
				
			||||||
	return res
 | 
						return res
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,28 @@ pub fn (g mut Gen) init() {
 | 
				
			||||||
	g.definitions.writeln('#include <inttypes.h>') // int64_t etc
 | 
						g.definitions.writeln('#include <inttypes.h>') // int64_t etc
 | 
				
			||||||
	g.definitions.writeln(c_builtin_types)
 | 
						g.definitions.writeln(c_builtin_types)
 | 
				
			||||||
	g.definitions.writeln(c_headers)
 | 
						g.definitions.writeln(c_headers)
 | 
				
			||||||
 | 
						// Multi return structs
 | 
				
			||||||
 | 
						// TODO move to a method
 | 
				
			||||||
 | 
						g.definitions.writeln('// multi return structs')
 | 
				
			||||||
 | 
						for typ in g.table.types {
 | 
				
			||||||
 | 
							// sym := g.table.get_type_symbol(typ)
 | 
				
			||||||
 | 
							if typ.kind != .multi_return {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							name := typ.name.replace('.', '__')
 | 
				
			||||||
 | 
							info := typ.info as table.MultiReturn
 | 
				
			||||||
 | 
							g.definitions.writeln('typedef struct {')
 | 
				
			||||||
 | 
							// 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('.', '__')
 | 
				
			||||||
 | 
								g.definitions.writeln('\t$type_name arg_${i+1};')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							g.definitions.writeln('} $name;\n')
 | 
				
			||||||
 | 
							// g.typedefs.writeln('typedef struct $name $name;')
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g.definitions.writeln('// end of definitions #endif')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn (g &Gen) save() {}
 | 
					pub fn (g &Gen) save() {}
 | 
				
			||||||
| 
						 | 
					@ -136,7 +158,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ast.FnDecl {
 | 
							ast.FnDecl {
 | 
				
			||||||
			if it.is_c {
 | 
								if it.is_c || it.name == 'malloc' {
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			g.reset_tmp_count()
 | 
								g.reset_tmp_count()
 | 
				
			||||||
| 
						 | 
					@ -147,21 +169,31 @@ fn (g mut Gen) stmt(node ast.Stmt) {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else {
 | 
								else {
 | 
				
			||||||
				type_sym := g.table.get_type_symbol(it.typ)
 | 
									type_sym := g.table.get_type_symbol(it.typ)
 | 
				
			||||||
				mut name := it.name.replace('.', '__')
 | 
									mut name := it.name
 | 
				
			||||||
				if it.is_method {
 | 
									if it.is_method {
 | 
				
			||||||
					name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
 | 
										name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				g.write('$type_sym.name ${name}(')
 | 
									name = name.replace('.', '__')
 | 
				
			||||||
				g.definitions.write('$type_sym.name ${name}(')
 | 
									// type_name := g.table.type_to_str(it.typ)
 | 
				
			||||||
 | 
									type_name := type_sym.name.replace('.', '__') // g.table.type_to_str(it.typ)
 | 
				
			||||||
 | 
									g.write('$type_name ${name}(')
 | 
				
			||||||
 | 
									g.definitions.write('$type_name ${name}(')
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								no_names := it.args.len > 0 && it.args[0].name == 'arg_1'
 | 
				
			||||||
			for i, arg in it.args {
 | 
								for i, arg in it.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
 | 
									mut arg_type_name := arg_type_sym.name.replace('.', '__')
 | 
				
			||||||
				if i == it.args.len - 1 && it.is_variadic {
 | 
									if i == it.args.len - 1 && it.is_variadic {
 | 
				
			||||||
					arg_type_name = 'variadic_$arg_type_sym.name'
 | 
										arg_type_name = 'variadic_$arg_type_sym.name'
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									if no_names {
 | 
				
			||||||
 | 
										g.write(arg_type_name)
 | 
				
			||||||
 | 
										g.definitions.write(arg_type_name)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else {
 | 
				
			||||||
					g.write(arg_type_name + ' ' + arg.name)
 | 
										g.write(arg_type_name + ' ' + arg.name)
 | 
				
			||||||
					g.definitions.write(arg_type_name + ' ' + arg.name)
 | 
										g.definitions.write(arg_type_name + ' ' + arg.name)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				if i < it.args.len - 1 {
 | 
									if i < it.args.len - 1 {
 | 
				
			||||||
					g.write(', ')
 | 
										g.write(', ')
 | 
				
			||||||
					g.definitions.write(', ')
 | 
										g.definitions.write(', ')
 | 
				
			||||||
| 
						 | 
					@ -239,13 +271,13 @@ fn (g mut Gen) stmt(node ast.Stmt) {
 | 
				
			||||||
			g.writeln(';')
 | 
								g.writeln(';')
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ast.StructDecl {
 | 
							ast.StructDecl {
 | 
				
			||||||
 | 
								name := it.name.replace('.', '__')
 | 
				
			||||||
			g.writeln('typedef struct {')
 | 
								g.writeln('typedef struct {')
 | 
				
			||||||
			for field in it.fields {
 | 
								for field in it.fields {
 | 
				
			||||||
				field_type_sym := g.table.get_type_symbol(field.typ)
 | 
									field_type_sym := g.table.get_type_symbol(field.typ)
 | 
				
			||||||
				g.writeln('\t$field_type_sym.name $field.name;')
 | 
									g.writeln('\t$field_type_sym.name $field.name;')
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			g.writeln('} $it.name;')
 | 
								g.writeln('} $name;')
 | 
				
			||||||
			name := it.name.replace('.', '__')
 | 
					 | 
				
			||||||
			g.typedefs.writeln('typedef struct $name $name;')
 | 
								g.typedefs.writeln('typedef struct $name $name;')
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ast.TypeDecl {
 | 
							ast.TypeDecl {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue