clean up the parser a bit; run vfmt; add x64 to ci
							parent
							
								
									b815878d60
								
							
						
					
					
						commit
						1e28c1d4fd
					
				|  | @ -120,7 +120,16 @@ jobs: | |||
|     - name: Freestanding | ||||
|       run: ./v -freestanding -o bare vlib/os/bare/bare_example_linux.v | ||||
|     - name: x64 machine code generation | ||||
|       run: echo "TODO" #cd examples/x64 && ../../v -x64 hello_world.v && ./hello_world | ||||
|       run: | | ||||
|         ./v -o vprod -prod v.v | ||||
|         cd tools | ||||
|         echo "Generating a 1m line V file..." | ||||
|         ../vprod run gen1m.v > 1m.v | ||||
|         echo "Building it..." | ||||
|         ../vprod -x64 1m.v | ||||
|         echo "Running it..." | ||||
|         ./1m | ||||
|       #run: echo "TODO" #cd examples/x64 && ../../v -x64 hello_world.v && ./hello_world | ||||
| 
 | ||||
| 
 | ||||
|   ubuntu-prebuilt: | ||||
|  |  | |||
|  | @ -1,16 +0,0 @@ | |||
| fn main() { | ||||
| 	for i in 0..10000 { | ||||
| 		println(' | ||||
| fn foo${i}() { | ||||
| 	x := $i | ||||
| 	mut a := x | ||||
| 	a += 2 | ||||
| 	println(a) | ||||
| 	a = 0 | ||||
| 	a = 1 | ||||
| } | ||||
| ') | ||||
| 	} | ||||
| 	println('fn main() {foo1()} ') | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,19 @@ | |||
| fn main() { | ||||
| 	println('fn println(a int) {}') | ||||
| 	println('fn print(a string) {}') | ||||
| 	for i in 0..100000 { | ||||
| 		println(' | ||||
| fn foo${i}() { | ||||
| 	x := $i | ||||
| 	mut a := x | ||||
| 	a += 2 | ||||
| 	println(a) | ||||
| 	a = 0 | ||||
| 	a = 1 | ||||
| } | ||||
| ') | ||||
| 	} | ||||
| 	//println('fn main() {foo1()} ')
 | ||||
| 	println('fn main() { print("1m DONE") } ') | ||||
| 
 | ||||
| } | ||||
|  | @ -840,7 +840,7 @@ fn (p mut Parser) type_decl() { | |||
| 				//println('child=$child_type_name parent=$name')
 | ||||
| 				mut t := p.find_type(child_type_name) | ||||
| 				if t.name == '' { | ||||
| 					p.error('qunknown type `$child_type_name`') | ||||
| 					p.error('unknown type `$child_type_name`') | ||||
| 				} | ||||
| 				t.parent = name | ||||
| 				p.table.rewrite_type(t) | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ import ( | |||
| pub type Expr = BinaryExpr | UnaryExpr | IfExpr | StringLiteral | IntegerLiteral | 	 | ||||
| FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | AssignExpr | PrefixExpr | ||||
| 
 | ||||
| pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt | AssignStmt | 	 | ||||
| pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt | 	 | ||||
| ForStmt | StructDecl | ||||
| // | IncDecStmt k
 | ||||
| // Stand-alone expression in a statement list.
 | ||||
|  | @ -72,7 +72,7 @@ pub: | |||
| 
 | ||||
| pub struct StructInit { | ||||
| pub: | ||||
| 	// typ    types.TypeIdent
 | ||||
| // typ    types.TypeIdent
 | ||||
| 	ti     types.TypeIdent | ||||
| 	fields []string | ||||
| 	exprs  []Expr | ||||
|  | @ -203,12 +203,15 @@ pub struct ReturnStmt { | |||
| 	results  []Expr | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| pub struct AssignStmt { | ||||
| pub: | ||||
| 	left  Expr | ||||
| 	right Expr | ||||
| 	op    token.Kind | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| 
 | ||||
| pub struct AssignExpr { | ||||
| pub: | ||||
|  |  | |||
|  | @ -43,17 +43,7 @@ fn (g mut Gen) stmt(node ast.Stmt) { | |||
| 	// println('cgen.stmt()')
 | ||||
| 	// g.writeln('//// stmt start')
 | ||||
| 	match node { | ||||
| 		ast.Import { | ||||
| 			 | ||||
| 		} | ||||
| 		/* | ||||
| 		ast.AssignStmt { | ||||
| 			g.expr(it.left) | ||||
| 			g.write(' $it.op.str() ') | ||||
| 			g.expr(it.right) | ||||
| 			g.writeln(';') | ||||
| 		} | ||||
| 		*/ | ||||
| 		ast.Import {} | ||||
| 		ast.FnDecl { | ||||
| 			is_main := it.name == 'main' | ||||
| 			if is_main { | ||||
|  |  | |||
|  | @ -33,12 +33,6 @@ pub fn (g mut JsGen) writeln(s string) { | |||
| 
 | ||||
| fn (g mut JsGen) stmt(node ast.Stmt) { | ||||
| 	match node { | ||||
| 		ast.AssignStmt { | ||||
| 			g.expr(it.left) | ||||
| 			g.write(' $it.op.str() ') | ||||
| 			g.expr(it.right) | ||||
| 			g.writeln(';') | ||||
| 		} | ||||
| 		ast.FnDecl { | ||||
| 			g.write('/** @return { $it.ti.name } **/\nfunction ${it.name}(') | ||||
| 			for arg in it.args { | ||||
|  |  | |||
|  | @ -310,12 +310,6 @@ pub fn (g mut Gen) call_fn(name string) { | |||
| 
 | ||||
| fn (g mut Gen) stmt(node ast.Stmt) { | ||||
| 	match node { | ||||
| 		ast.AssignStmt { | ||||
| 			g.expr(it.left) | ||||
| 			g.write(' $it.op.str() ') | ||||
| 			g.expr(it.right) | ||||
| 			g.writeln(';') | ||||
| 		} | ||||
| 		ast.FnDecl { | ||||
| 			is_main := it.name == 'main' | ||||
| 			if is_main { | ||||
|  | @ -332,44 +326,19 @@ fn (g mut Gen) stmt(node ast.Stmt) { | |||
| 			g.ret() | ||||
| 		} | ||||
| 		ast.Return { | ||||
| 			g.write('return ') | ||||
| 			g.expr(it.expr) | ||||
| 			g.writeln(';') | ||||
| 		} | ||||
| 		ast.VarDecl { | ||||
| 			g.write('$it.ti.name $it.name = ') | ||||
| 			g.expr(it.expr) | ||||
| 			g.writeln(';') | ||||
| 		} | ||||
| 		ast.ForStmt { | ||||
| 			if it.is_in {} | ||||
| 			g.write('while (') | ||||
| 			g.expr(it.cond) | ||||
| 			g.writeln(') {') | ||||
| 			for stmt in it.stmts { | ||||
| 				g.stmt(stmt) | ||||
| 			} | ||||
| 			g.writeln('}') | ||||
| 		} | ||||
| 		ast.StructDecl { | ||||
| 			g.writeln('typedef struct {') | ||||
| 			for field in it.fields { | ||||
| 				g.writeln('\t$field.ti.name $field.name;') | ||||
| 			} | ||||
| 			g.writeln('} $it.name;') | ||||
| 		} | ||||
| 		ast.ExprStmt { | ||||
| 			g.expr(it.expr) | ||||
| 			match it.expr { | ||||
| 				// no ; after an if expression
 | ||||
| 				ast.IfExpr {} | ||||
| 				else { | ||||
| 					g.writeln(';') | ||||
| 				} | ||||
| 	} | ||||
| 		} | ||||
| 		else { | ||||
| 			verror('cgen.stmt(): bad node') | ||||
| 			verror('x64.stmt(): bad node') | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -377,37 +346,16 @@ fn (g mut Gen) stmt(node ast.Stmt) { | |||
| fn (g mut Gen) expr(node ast.Expr) { | ||||
| 	// println('cgen expr()')
 | ||||
| 	match node { | ||||
| 		ast.IntegerLiteral { | ||||
| 			g.write(it.val.str()) | ||||
| 		} | ||||
| 		ast.FloatLiteral { | ||||
| 			g.write(it.val) | ||||
| 		} | ||||
| 		ast.AssignExpr {} | ||||
| 		ast.IntegerLiteral {} | ||||
| 		ast.FloatLiteral {} | ||||
| 		ast.UnaryExpr { | ||||
| 			g.expr(it.left) | ||||
| 			g.write(it.op.str()) | ||||
| 		} | ||||
| 		ast.StringLiteral { | ||||
| 			g.write('tos3("$it.val")') | ||||
| 		} | ||||
| 		ast.BinaryExpr { | ||||
| 			g.expr(it.left) | ||||
| 			g.write(' $it.op.str() ') | ||||
| 			g.expr(it.right) | ||||
| 			// if ti.type_name != typ2.name {
 | ||||
| 			// verror('bad types $ti.type_name $typ2.name')
 | ||||
| 			// }
 | ||||
| 		} | ||||
| 		ast.StringLiteral {} | ||||
| 		ast.BinaryExpr {} | ||||
| 		// `user := User{name: 'Bob'}`
 | ||||
| 		ast.StructInit { | ||||
| 			g.writeln('($it.ti.name){') | ||||
| 			for i, field in it.fields { | ||||
| 				g.write('\t.$field = ') | ||||
| 				g.expr(it.exprs[i]) | ||||
| 				g.writeln(', ') | ||||
| 			} | ||||
| 			g.write('}') | ||||
| 		} | ||||
| 		ast.StructInit {} | ||||
| 		ast.CallExpr { | ||||
| 			if it.name == 'println' || it.name == 'print' { | ||||
| 				expr := it.args[0] | ||||
|  | @ -425,43 +373,12 @@ fn (g mut Gen) expr(node ast.Expr) { | |||
| 			*/ | ||||
| 
 | ||||
| 		} | ||||
| 		ast.ArrayInit { | ||||
| 			g.writeln('new_array_from_c_array($it.exprs.len, $it.exprs.len, sizeof($it.ti.name), {\t') | ||||
| 			for expr in it.exprs { | ||||
| 				g.expr(expr) | ||||
| 				g.write(', ') | ||||
| 			} | ||||
| 			g.write('\n})') | ||||
| 		} | ||||
| 		ast.Ident { | ||||
| 			g.write('$it.name') | ||||
| 		} | ||||
| 		ast.BoolLiteral { | ||||
| 			if it.val == true { | ||||
| 				g.write('true') | ||||
| 			} | ||||
| 			else { | ||||
| 				g.write('false') | ||||
| 			} | ||||
| 		} | ||||
| 		ast.IfExpr { | ||||
| 			g.write('if (') | ||||
| 			g.expr(it.cond) | ||||
| 			g.writeln(') {') | ||||
| 			for stmt in it.stmts { | ||||
| 				g.stmt(stmt) | ||||
| 			} | ||||
| 			g.writeln('}') | ||||
| 			if it.else_stmts.len > 0 { | ||||
| 				g.writeln('else { ') | ||||
| 				for stmt in it.else_stmts { | ||||
| 					g.stmt(stmt) | ||||
| 				} | ||||
| 				g.writeln('}') | ||||
| 			} | ||||
| 		} | ||||
| 		ast.ArrayInit {} | ||||
| 		ast.Ident {} | ||||
| 		ast.BoolLiteral {} | ||||
| 		ast.IfExpr {} | ||||
| 		else { | ||||
| 			println(term.red('cgen.expr(): bad node')) | ||||
| 			//println(term.red('x64.expr(): bad node'))
 | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| module types | ||||
| 
 | ||||
| pub enum Kind { | ||||
| 	_placeholder, | ||||
| 	_placeholder | ||||
| 	_void, | ||||
| 	_voidptr, | ||||
| 	_charptr, | ||||
|  | @ -32,17 +32,20 @@ pub enum Kind { | |||
| 	_variadic | ||||
| } | ||||
| 
 | ||||
| pub type Type = Placeholder | Void | Voidptr | Charptr | Byteptr | Const | Enum | Struct | 	 | ||||
| Int | Float | String | Char | Byte | Bool | Array | ArrayFixed | Map | MultiReturn | Variadic | ||||
| 
 | ||||
| pub struct TypeIdent { | ||||
| pub: | ||||
| 	idx  int | ||||
| 	kind Kind | ||||
| 	name string | ||||
| 	nr_muls   int | ||||
| 	idx     int | ||||
| 	kind    Kind | ||||
| 	name    string | ||||
| 	nr_muls int | ||||
| } | ||||
| 
 | ||||
| [inline] | ||||
| pub fn new_ti(kind Kind, name string, idx int, nr_muls int) TypeIdent { | ||||
|     return TypeIdent{ | ||||
| 	return TypeIdent{ | ||||
| 		idx: idx | ||||
| 		kind: kind | ||||
| 		name: name | ||||
|  | @ -52,7 +55,7 @@ pub fn new_ti(kind Kind, name string, idx int, nr_muls int) TypeIdent { | |||
| 
 | ||||
| [inline] | ||||
| pub fn new_base_ti(kind Kind, nr_muls int) TypeIdent { | ||||
|     return TypeIdent{ | ||||
| 	return TypeIdent{ | ||||
| 		kind: kind | ||||
| 		name: kind.str() | ||||
| 		nr_muls: nr_muls | ||||
|  | @ -61,22 +64,22 @@ pub fn new_base_ti(kind Kind, nr_muls int) TypeIdent { | |||
| 
 | ||||
| [inline] | ||||
| pub fn (ti &TypeIdent) is_ptr() bool { | ||||
|     return ti.nr_muls > 0 | ||||
| 	return ti.nr_muls > 0 | ||||
| } | ||||
| 
 | ||||
| [inline] | ||||
| pub fn (ti &TypeIdent) is_int() bool { | ||||
|     return ti.kind in [._i8, ._i16, ._int, ._i64, ._byte, ._u16, ._u32, ._u64] | ||||
| 	return ti.kind in [._i8, ._i16, ._int, ._i64, ._byte, ._u16, ._u32, ._u64] | ||||
| } | ||||
| 
 | ||||
| [inline] | ||||
| pub fn (ti &TypeIdent) is_float() bool { | ||||
|     return ti.kind in [._f32, ._f64] | ||||
| 	return ti.kind in [._f32, ._f64] | ||||
| } | ||||
| 
 | ||||
| [inline] | ||||
| pub fn (ti &TypeIdent) is_number() bool { | ||||
|     return ti.is_int() || ti.is_float() | ||||
| 	return ti.is_int() || ti.is_float() | ||||
| } | ||||
| 
 | ||||
| pub fn (ti &TypeIdent) str() string { | ||||
|  | @ -92,81 +95,80 @@ pub fn check(got, expected &TypeIdent) bool { | |||
| 
 | ||||
| pub fn (k Kind) str() string { | ||||
| 	k_str := match k { | ||||
| 		._placeholder { | ||||
| 		._placeholder{ | ||||
| 			'placeholder' | ||||
| 		} | ||||
| 		._void  { | ||||
| 		._void{ | ||||
| 			'void' | ||||
| 		} | ||||
| 		._voidptr  { | ||||
| 		._voidptr{ | ||||
| 			'voidptr' | ||||
| 		} | ||||
| 		._charptr  { | ||||
| 		._charptr{ | ||||
| 			'charptr' | ||||
| 		} | ||||
| 		._byteptr  { | ||||
| 		._byteptr{ | ||||
| 			'byteptr' | ||||
| 		} | ||||
| 		._const  { | ||||
| 		._const{ | ||||
| 			'const' | ||||
| 		} | ||||
| 		._enum  { | ||||
| 		._enum{ | ||||
| 			'enum' | ||||
| 		} | ||||
| 		._struct  { | ||||
| 		._struct{ | ||||
| 			'struct' | ||||
| 		} | ||||
| 		._int  { | ||||
| 		._int{ | ||||
| 			'int' | ||||
| 		} | ||||
| 		._i8  { | ||||
| 		._i8{ | ||||
| 			'i8' | ||||
| 		} | ||||
| 		._i16  { | ||||
| 		._i16{ | ||||
| 			'i16' | ||||
| 		} | ||||
| 		._i64  { | ||||
| 		._i64{ | ||||
| 			'i64' | ||||
| 		} | ||||
| 		._byte  { | ||||
| 		._byte{ | ||||
| 			'byte' | ||||
| 		} | ||||
| 		._u16  { | ||||
| 		._u16{ | ||||
| 			'u18' | ||||
| 		} | ||||
| 		._f32  { | ||||
| 		._f32{ | ||||
| 			'f32' | ||||
| 		} | ||||
| 		._f64  { | ||||
| 		._f64{ | ||||
| 			'f64' | ||||
| 		} | ||||
| 		._string  { | ||||
| 		._string{ | ||||
| 			'string' | ||||
| 		} | ||||
| 		._char  { | ||||
| 		._char{ | ||||
| 			'char' | ||||
| 		} | ||||
| 		._bool  { | ||||
| 		._bool{ | ||||
| 			'bool' | ||||
| 		} | ||||
| 		._array  { | ||||
| 		._array{ | ||||
| 			'array' | ||||
| 		} | ||||
| 		._array_fixed  { | ||||
| 		._array_fixed{ | ||||
| 			'array_fixed' | ||||
| 		} | ||||
| 		._map  { | ||||
| 		._map{ | ||||
| 			'map' | ||||
| 		} | ||||
| 		._multi_return  { | ||||
| 		._multi_return{ | ||||
| 			'multi_return' | ||||
| 		} | ||||
| 		._variadic { | ||||
| 		._variadic{ | ||||
| 			'variadic' | ||||
| 		} | ||||
| 		else { | ||||
| 			'unknown' | ||||
| 		} | ||||
| 			'unknown'} | ||||
| 	} | ||||
| 	return k_str | ||||
| } | ||||
|  | @ -175,17 +177,13 @@ pub fn (kinds []Kind) str() string { | |||
| 	mut kinds_str := '' | ||||
| 	for i, k in kinds { | ||||
| 		kinds_str += k.str() | ||||
| 		if i < kinds.len-1 { | ||||
| 		if i < kinds.len - 1 { | ||||
| 			kinds_str += '_' | ||||
| 		} | ||||
| 	} | ||||
| 	return kinds_str | ||||
| } | ||||
| 
 | ||||
| pub type Type = Placeholder | Void | Voidptr | Charptr | Byteptr | Const | Enum | Struct | | ||||
| 	Int | Float | String | Char | Byte | Bool | Array | ArrayFixed | Map | MultiReturn | Variadic | ||||
| 
 | ||||
| 
 | ||||
| pub struct Placeholder { | ||||
| pub: | ||||
| 	idx  int | ||||
|  | @ -290,47 +288,107 @@ pub: | |||
| 	type_idx  int | ||||
| } | ||||
| 
 | ||||
| pub fn (t Void) str() string { return 'void' } | ||||
| pub fn (t Voidptr) str() string { return 'voidptr' } | ||||
| pub fn (t Charptr) str() string { return 'charptr' } | ||||
| pub fn (t Byteptr) str() string { return 'byteptr' } | ||||
| pub fn (t Const) str() string { return t.name } | ||||
| pub fn (t Enum) str() string { return t.name } | ||||
| pub fn (t Struct) str() string { return t.name } | ||||
| pub fn (t Int) str() string { return if t.is_unsigned {'u$t.bit_size' } else { 'i$t.bit_size' } } | ||||
| pub fn (t Float) str() string { return 'f$t.bit_size' } | ||||
| pub fn (t String) str() string { return 'string' } | ||||
| pub fn (t Char) str() string { return 'char' } | ||||
| pub fn (t Byte) str() string { return 'byte' } | ||||
| pub fn (t Array) str() string { return t.name } | ||||
| pub fn (t ArrayFixed) str() string { return t.name } | ||||
| pub fn (t Map) str() string { return t.name } | ||||
| pub fn (t MultiReturn) str() string { return t.name } | ||||
| pub fn (t Variadic) str() string { return 'variadic_$t.type_kind.str()' } | ||||
| pub fn (t Void) str() string { | ||||
| 	return 'void' | ||||
| } | ||||
| 
 | ||||
| pub fn (t Voidptr) str() string { | ||||
| 	return 'voidptr' | ||||
| } | ||||
| 
 | ||||
| pub fn (t Charptr) str() string { | ||||
| 	return 'charptr' | ||||
| } | ||||
| 
 | ||||
| pub fn (t Byteptr) str() string { | ||||
| 	return 'byteptr' | ||||
| } | ||||
| 
 | ||||
| pub fn (t Const) str() string { | ||||
| 	return t.name | ||||
| } | ||||
| 
 | ||||
| pub fn (t Enum) str() string { | ||||
| 	return t.name | ||||
| } | ||||
| 
 | ||||
| pub fn (t Struct) str() string { | ||||
| 	return t.name | ||||
| } | ||||
| 
 | ||||
| pub fn (t Int) str() string { | ||||
| 	return if t.is_unsigned { 'u$t.bit_size' } else { 'i$t.bit_size' } | ||||
| } | ||||
| 
 | ||||
| pub fn (t Float) str() string { | ||||
| 	return 'f$t.bit_size' | ||||
| } | ||||
| 
 | ||||
| pub fn (t String) str() string { | ||||
| 	return 'string' | ||||
| } | ||||
| 
 | ||||
| pub fn (t Char) str() string { | ||||
| 	return 'char' | ||||
| } | ||||
| 
 | ||||
| pub fn (t Byte) str() string { | ||||
| 	return 'byte' | ||||
| } | ||||
| 
 | ||||
| pub fn (t Array) str() string { | ||||
| 	return t.name | ||||
| } | ||||
| 
 | ||||
| pub fn (t ArrayFixed) str() string { | ||||
| 	return t.name | ||||
| } | ||||
| 
 | ||||
| pub fn (t Map) str() string { | ||||
| 	return t.name | ||||
| } | ||||
| 
 | ||||
| pub fn (t MultiReturn) str() string { | ||||
| 	return t.name | ||||
| } | ||||
| 
 | ||||
| pub fn (t Variadic) str() string { | ||||
| 	return 'variadic_$t.type_kind.str()' | ||||
| } | ||||
| 
 | ||||
| pub const ( | ||||
| 	void_type    = Void{} | ||||
| 	void_type = Void{} | ||||
| 	voidptr_type = Voidptr{} | ||||
| 	charptr_type = Charptr{} | ||||
| 	byteptr_type = Byteptr{} | ||||
| 	i8_type      = Int{8, false} | ||||
| 	i16_type     = Int{16, false} | ||||
| 	int_type     = Int{32, false} | ||||
| 	i64_type     = Int{64, false} | ||||
| 	byte_type    = Int{8, true} | ||||
| 	u16_type     = Int{16, true} | ||||
| 	u32_type     = Int{32, true} | ||||
| 	u64_type     = Int{64, true} | ||||
| 	f32_type     = Float{32} | ||||
| 	f64_type     = Float{64} | ||||
| 	string_type  = String{} | ||||
| 	char_type    = Char{} | ||||
| 	bool_type    = Bool{} | ||||
| 	i8_type = Int{ | ||||
| 		8,false} | ||||
| 	i16_type = Int{ | ||||
| 		16,false} | ||||
| 	int_type = Int{ | ||||
| 		32,false} | ||||
| 	i64_type = Int{ | ||||
| 		64,false} | ||||
| 	byte_type = Int{ | ||||
| 		8,true} | ||||
| 	u16_type = Int{ | ||||
| 		16,true} | ||||
| 	u32_type = Int{ | ||||
| 		32,true} | ||||
| 	u64_type = Int{ | ||||
| 		64,true} | ||||
| 	f32_type = Float{ | ||||
| 		32} | ||||
| 	f64_type = Float{ | ||||
| 		64} | ||||
| 	string_type = String{} | ||||
| 	char_type = Char{} | ||||
| 	bool_type = Bool{} | ||||
| ) | ||||
| 
 | ||||
| pub const ( | ||||
| 	void_ti   = new_base_ti(._void, 0) | ||||
| 	int_ti    = new_base_ti(._int, 0) | ||||
| 	void_ti = new_base_ti(._void, 0) | ||||
| 	int_ti = new_base_ti(._int, 0) | ||||
| 	string_ti = new_base_ti(._string, 0) | ||||
| 	bool_ti   = new_base_ti(._bool, 0) | ||||
| 	bool_ti = new_base_ti(._bool, 0) | ||||
| ) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue