cgen: error fixes; table: simplify; compiler tests
parent
b43ac2783d
commit
4b4c47461b
|
@ -107,6 +107,7 @@ pub:
|
|||
mut_pos int // mut:
|
||||
pub_pos int // pub:
|
||||
pub_mut_pos int // pub mut:
|
||||
is_c bool
|
||||
}
|
||||
|
||||
pub struct StructInit {
|
||||
|
@ -492,8 +493,8 @@ pub:
|
|||
pos token.Position
|
||||
left Expr
|
||||
val Expr
|
||||
// mut:
|
||||
// left_type table.Type
|
||||
mut:
|
||||
left_type table.Type
|
||||
}
|
||||
|
||||
pub struct GotoLabel {
|
||||
|
|
|
@ -121,7 +121,6 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type
|
|||
else {}
|
||||
}
|
||||
if c.is_amp {
|
||||
println('XAXAXAX')
|
||||
return table.type_to_ptr(struct_init.typ)
|
||||
}
|
||||
return struct_init.typ
|
||||
|
@ -153,7 +152,7 @@ pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type {
|
|||
return left_type
|
||||
}
|
||||
|
||||
fn (c mut Checker) assign_expr(assign_expr ast.AssignExpr) {
|
||||
fn (c mut Checker) assign_expr(assign_expr mut ast.AssignExpr) {
|
||||
match assign_expr.left {
|
||||
ast.Ident {
|
||||
if it.kind == .blank_ident {
|
||||
|
@ -164,6 +163,7 @@ fn (c mut Checker) assign_expr(assign_expr ast.AssignExpr) {
|
|||
}
|
||||
left_type := c.expr(assign_expr.left)
|
||||
c.expected_type = left_type
|
||||
assign_expr.left_type = left_type
|
||||
// assign_expr.left_type = left_type
|
||||
// t := c.table.get_type_symbol(left_type)
|
||||
// println('setting exp type to $c.expected_type $t.name')
|
||||
|
@ -594,7 +594,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
|
|||
return it.typ
|
||||
}
|
||||
ast.AssignExpr {
|
||||
c.assign_expr(it)
|
||||
c.assign_expr(mut it)
|
||||
}
|
||||
ast.Assoc {
|
||||
scope := c.file.scope.innermost(it.pos.pos)
|
||||
|
|
|
@ -58,6 +58,13 @@ pub fn (g &Gen) typ(t table.Type) string {
|
|||
if nr_muls > 0 {
|
||||
styp += strings.repeat(`*`, nr_muls)
|
||||
}
|
||||
if styp.starts_with('C__') {
|
||||
styp = styp[3..]
|
||||
}
|
||||
if styp == 'stat' {
|
||||
// TODO perf and other C structs
|
||||
styp = 'struct stat'
|
||||
}
|
||||
return styp
|
||||
}
|
||||
|
||||
|
@ -286,8 +293,10 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
|||
// g.writeln('\t$field_type_sym.name $field.name;')
|
||||
// }
|
||||
// g.writeln('} $name;')
|
||||
if !it.is_c {
|
||||
g.typedefs.writeln('typedef struct $name $name;')
|
||||
}
|
||||
}
|
||||
ast.TypeDecl {
|
||||
g.writeln('// type')
|
||||
}
|
||||
|
@ -302,6 +311,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
|||
|
||||
fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||
// multi return
|
||||
// g.write('/*assign*/')
|
||||
if assign_stmt.left.len > assign_stmt.right.len {
|
||||
mut return_type := table.void_type
|
||||
match assign_stmt.right[0] {
|
||||
|
@ -399,6 +409,9 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
|||
if name.starts_with('_op_') {
|
||||
name = op_to_fn_name(name)
|
||||
}
|
||||
if name == 'exit' {
|
||||
name = 'v_exit'
|
||||
}
|
||||
// type_name := g.table.type_to_str(it.return_type)
|
||||
type_name := g.typ(it.return_type)
|
||||
g.write('$type_name ${name}(')
|
||||
|
@ -503,17 +516,30 @@ fn (g mut Gen) expr(node ast.Expr) {
|
|||
}
|
||||
ast.AssignExpr {
|
||||
g.is_assign_expr = true
|
||||
mut str_add := false
|
||||
if it.left_type == table.string_type_idx && it.op == .plus_assign {
|
||||
// str += str2 => `str = string_add(str, str2)`
|
||||
g.expr(it.left)
|
||||
g.write(' = string_add(')
|
||||
str_add = true
|
||||
}
|
||||
g.expr(it.left)
|
||||
// arr[i] = val => `array_set(arr, i, val)`, not `array_get(arr, i) = val`
|
||||
if !g.is_array_set {
|
||||
if !g.is_array_set && !str_add {
|
||||
g.write(' $it.op.str() ')
|
||||
}
|
||||
else if str_add {
|
||||
g.write(', ')
|
||||
}
|
||||
g.is_assign_expr = false
|
||||
g.expr(it.val)
|
||||
if g.is_array_set {
|
||||
g.write(' })')
|
||||
g.is_array_set = false
|
||||
}
|
||||
else if str_add {
|
||||
g.write(')')
|
||||
}
|
||||
}
|
||||
ast.Assoc {
|
||||
g.write('/* assoc */')
|
||||
|
@ -523,6 +549,9 @@ fn (g mut Gen) expr(node ast.Expr) {
|
|||
}
|
||||
ast.CallExpr {
|
||||
mut name := it.name.replace('.', '__')
|
||||
if name == 'exit' {
|
||||
name = 'v_exit'
|
||||
}
|
||||
if it.is_c {
|
||||
// Skip "C__"
|
||||
g.is_c_call = true
|
||||
|
@ -834,6 +863,9 @@ fn (g mut Gen) expr(node ast.Expr) {
|
|||
g.expr(it.exprs[i])
|
||||
g.writeln(', ')
|
||||
}
|
||||
if it.fields.len == 0 {
|
||||
g.write('0')
|
||||
}
|
||||
g.write('}')
|
||||
if g.is_amp {
|
||||
g.write(', sizeof($styp))')
|
||||
|
@ -865,6 +897,7 @@ fn (g mut Gen) expr(node ast.Expr) {
|
|||
}
|
||||
|
||||
fn (g mut Gen) infix_expr(node ast.InfixExpr) {
|
||||
// g.write('/*infix*/')
|
||||
// if it.left_type == table.string_type_idx {
|
||||
// g.write('/*$node.left_type str*/')
|
||||
// }
|
||||
|
@ -1103,6 +1136,9 @@ fn (g mut Gen) write_sorted_types() {
|
|||
|
||||
fn (g mut Gen) write_types(types []table.TypeSymbol) {
|
||||
for typ in types {
|
||||
if typ.name.starts_with('C.') {
|
||||
continue
|
||||
}
|
||||
// sym := g.table.get_type_symbol(typ)
|
||||
match typ.info {
|
||||
table.Struct {
|
||||
|
|
|
@ -49,6 +49,8 @@ fn compare_texts(a, b, path string) bool {
|
|||
println('${path}: got\n$a')
|
||||
println('${term_fail} ${i}')
|
||||
println(term.red('i=$i "$line_a" expected="$line_b"'))
|
||||
// println(lines_b[i + 1])
|
||||
// println(lines_b[i + 2])
|
||||
// exit(1)
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ int main() {
|
|||
println(int_str(localmod__pub_int_const));
|
||||
int g = ((int)(3.0));
|
||||
byte* bytes = ((byte*)(0));
|
||||
User* user_ptr = (User*)memdup(&(User){}, sizeof(User));
|
||||
User* user_ptr = (User*)memdup(&(User){0}, sizeof(User));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ i < 10; i++) {
|
|||
});
|
||||
array_User users = new_array_from_c_array(1, 1, sizeof(array_User), (User[]){
|
||||
(User){
|
||||
},
|
||||
0},
|
||||
});
|
||||
bool b = (*(bool*)array_get(bools, 0));
|
||||
array_string mystrings = new_array_from_c_array(2, 2, sizeof(array_string), (string[]){
|
||||
|
|
|
@ -30,7 +30,7 @@ void init_user() {
|
|||
|
||||
User get_user() {
|
||||
User user = (User){
|
||||
};
|
||||
0};
|
||||
return user;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ tos3(""),
|
|||
|
||||
int main() {
|
||||
User user = (User){
|
||||
};
|
||||
0};
|
||||
user.age = 10;
|
||||
user.age++;
|
||||
user.name = tos3("bob");
|
||||
|
|
|
@ -1440,6 +1440,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
|||
mut_pos: mut_pos
|
||||
pub_pos: pub_pos
|
||||
pub_mut_pos: pub_mut_pos
|
||||
is_c: is_c
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,469 +3,3 @@
|
|||
// that can be found in the LICENSE file.
|
||||
module table
|
||||
|
||||
import (
|
||||
strings
|
||||
)
|
||||
|
||||
pub type TypeInfo = Array | ArrayFixed | Map | Struct |
|
||||
MultiReturn | Alias | Enum | SumType | Fn
|
||||
|
||||
pub struct TypeSymbol {
|
||||
pub:
|
||||
parent_idx int
|
||||
mut:
|
||||
info TypeInfo
|
||||
kind Kind
|
||||
name string
|
||||
methods []Fn
|
||||
// is_sum bool
|
||||
}
|
||||
|
||||
pub const (
|
||||
// primitive types
|
||||
void_type_idx = 1
|
||||
voidptr_type_idx = 2
|
||||
byteptr_type_idx = 3
|
||||
charptr_type_idx = 4
|
||||
i8_type_idx = 5
|
||||
i16_type_idx = 6
|
||||
int_type_idx = 7
|
||||
i64_type_idx = 8
|
||||
byte_type_idx = 9
|
||||
u16_type_idx = 10
|
||||
u32_type_idx = 11
|
||||
u64_type_idx = 12
|
||||
f32_type_idx = 13
|
||||
f64_type_idx = 14
|
||||
char_type_idx = 15
|
||||
bool_type_idx = 16
|
||||
none_type_idx = 17
|
||||
// advanced / defined from v structs
|
||||
string_type_idx = 18
|
||||
array_type_idx = 19
|
||||
map_type_idx = 20
|
||||
)
|
||||
|
||||
pub const (
|
||||
builtin_type_names = ['void', 'voidptr', 'charptr', 'byteptr', 'i8', 'i16', 'int', 'i64', 'u16', 'u32', 'u64',
|
||||
'f32', 'f64', 'string', 'char', 'byte', 'bool', 'none', 'array', 'array_fixed', 'map', 'struct',
|
||||
'mapnode', 'ustring']
|
||||
)
|
||||
|
||||
pub struct MultiReturn {
|
||||
pub:
|
||||
name string
|
||||
mut:
|
||||
types []Type
|
||||
}
|
||||
|
||||
pub enum Kind {
|
||||
placeholder
|
||||
void
|
||||
voidptr
|
||||
byteptr
|
||||
charptr
|
||||
i8
|
||||
i16
|
||||
int
|
||||
i64
|
||||
byte
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
f32
|
||||
f64
|
||||
char
|
||||
bool
|
||||
none_
|
||||
string
|
||||
array
|
||||
array_fixed
|
||||
map
|
||||
struct_
|
||||
multi_return
|
||||
sum_type
|
||||
alias
|
||||
enum_
|
||||
function
|
||||
}
|
||||
|
||||
pub fn (t &TypeSymbol) str() string {
|
||||
return t.name.replace('array_', '[]')
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) enum_info() Enum {
|
||||
match t.info {
|
||||
Enum {
|
||||
return it
|
||||
}
|
||||
else {
|
||||
panic('TypeSymbol.enum_info(): no enum info for type: $t.name')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) mr_info() MultiReturn {
|
||||
match t.info {
|
||||
MultiReturn {
|
||||
return it
|
||||
}
|
||||
else {
|
||||
panic('TypeSymbol.mr_info(): no multi return info for type: $t.name')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) array_info() Array {
|
||||
match t.info {
|
||||
Array {
|
||||
return it
|
||||
}
|
||||
else {
|
||||
panic('TypeSymbol.array_info(): no array info for type: $t.name')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) array_fixed_info() ArrayFixed {
|
||||
match t.info {
|
||||
ArrayFixed {
|
||||
return it
|
||||
}
|
||||
else {
|
||||
panic('TypeSymbol.array_fixed(): no array fixed info for type: $t.name')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) map_info() Map {
|
||||
match t.info {
|
||||
Map {
|
||||
return it
|
||||
}
|
||||
else {
|
||||
panic('TypeSymbol.map_info(): no map info for type: $t.name')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn (t TypeSymbol) str() string {
|
||||
return t.name
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
pub fn (t mut Table) register_builtin_type_symbols() {
|
||||
// reserve index 0 so nothing can go there
|
||||
// save index check, 0 will mean not found
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .placeholder
|
||||
name: 'reserved_0'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .void
|
||||
name: 'void'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .voidptr
|
||||
name: 'voidptr'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .byteptr
|
||||
name: 'byteptr'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .charptr
|
||||
name: 'charptr'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .i8
|
||||
name: 'i8'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .i16
|
||||
name: 'i16'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .int
|
||||
name: 'int'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .i64
|
||||
name: 'i64'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .byte
|
||||
name: 'byte'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .u16
|
||||
name: 'u16'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .u32
|
||||
name: 'u32'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .u64
|
||||
name: 'u64'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .f32
|
||||
name: 'f32'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .f64
|
||||
name: 'f64'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .char
|
||||
name: 'char'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .bool
|
||||
name: 'bool'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .none_
|
||||
name: 'none'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .string
|
||||
name: 'string'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .array
|
||||
name: 'array'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .map
|
||||
name: 'map'
|
||||
})
|
||||
// TODO: remove. for v1 map compatibility
|
||||
map_string_string_idx := t.find_or_register_map(string_type, string_type)
|
||||
map_string_int_idx := t.find_or_register_map(string_type, int_type)
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .alias
|
||||
name: 'map_string'
|
||||
parent_idx: map_string_string_idx
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .alias
|
||||
name: 'map_int'
|
||||
parent_idx: map_string_int_idx
|
||||
})
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) is_int() bool {
|
||||
return t.kind in [.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64]
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) is_float() bool {
|
||||
return t.kind in [.f32, .f64]
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) is_number() bool {
|
||||
return t.is_int() || t.is_float()
|
||||
}
|
||||
|
||||
pub fn (k Kind) str() string {
|
||||
k_str := match k {
|
||||
.placeholder{
|
||||
'placeholder'
|
||||
}
|
||||
.void{
|
||||
'void'
|
||||
}
|
||||
.voidptr{
|
||||
'voidptr'
|
||||
}
|
||||
.charptr{
|
||||
'charptr'
|
||||
}
|
||||
.byteptr{
|
||||
'byteptr'
|
||||
}
|
||||
.struct_{
|
||||
'struct'
|
||||
}
|
||||
.int{
|
||||
'int'
|
||||
}
|
||||
.i8{
|
||||
'i8'
|
||||
}
|
||||
.i16{
|
||||
'i16'
|
||||
}
|
||||
.i64{
|
||||
'i64'
|
||||
}
|
||||
.byte{
|
||||
'byte'
|
||||
}
|
||||
.u16{
|
||||
'u16'
|
||||
}
|
||||
.u32{
|
||||
'u32'
|
||||
}
|
||||
.u64{
|
||||
'u64'
|
||||
}
|
||||
.f32{
|
||||
'f32'
|
||||
}
|
||||
.f64{
|
||||
'f64'
|
||||
}
|
||||
.string{
|
||||
'string'
|
||||
}
|
||||
.char{
|
||||
'char'
|
||||
}
|
||||
.bool{
|
||||
'bool'
|
||||
}
|
||||
.none_{
|
||||
'none'
|
||||
}
|
||||
.array{
|
||||
'array'
|
||||
}
|
||||
.array_fixed{
|
||||
'array_fixed'
|
||||
}
|
||||
.map{
|
||||
'map'
|
||||
}
|
||||
.multi_return{
|
||||
'multi_return'
|
||||
}
|
||||
.sum_type{
|
||||
'sum_type'
|
||||
}
|
||||
.alias{
|
||||
'alias'
|
||||
}
|
||||
.enum_{
|
||||
'enum'
|
||||
}
|
||||
else {
|
||||
'unknown'}
|
||||
}
|
||||
return k_str
|
||||
}
|
||||
|
||||
pub fn (kinds []Kind) str() string {
|
||||
mut kinds_str := ''
|
||||
for i, k in kinds {
|
||||
kinds_str += k.str()
|
||||
if i < kinds.len - 1 {
|
||||
kinds_str += '_'
|
||||
}
|
||||
}
|
||||
return kinds_str
|
||||
}
|
||||
|
||||
pub struct Struct {
|
||||
pub mut:
|
||||
fields []Field
|
||||
}
|
||||
|
||||
pub struct Enum {
|
||||
pub mut:
|
||||
vals []string
|
||||
}
|
||||
|
||||
pub struct Alias {
|
||||
pub:
|
||||
foo string
|
||||
}
|
||||
|
||||
pub struct Field {
|
||||
pub:
|
||||
name string
|
||||
mut:
|
||||
typ Type
|
||||
}
|
||||
|
||||
pub struct Array {
|
||||
pub:
|
||||
nr_dims int
|
||||
mut:
|
||||
elem_type Type
|
||||
}
|
||||
|
||||
pub struct ArrayFixed {
|
||||
pub:
|
||||
nr_dims int
|
||||
size int
|
||||
mut:
|
||||
elem_type Type
|
||||
}
|
||||
|
||||
pub struct Map {
|
||||
pub mut:
|
||||
key_type Type
|
||||
value_type Type
|
||||
}
|
||||
|
||||
pub struct SumType {
|
||||
pub:
|
||||
variants []Type
|
||||
}
|
||||
|
||||
pub fn (table &Table) type_to_str(t Type) string {
|
||||
sym := table.get_type_symbol(t)
|
||||
if sym.kind == .multi_return {
|
||||
mut res := '('
|
||||
mr_info := sym.info as MultiReturn
|
||||
for i, typ in mr_info.types {
|
||||
res += table.type_to_str(typ)
|
||||
if i < mr_info.types.len - 1 {
|
||||
res += ', '
|
||||
}
|
||||
}
|
||||
res += ')'
|
||||
return res
|
||||
}
|
||||
mut res := sym.name
|
||||
if sym.kind == .array {
|
||||
res = res.replace('array_', '[]')
|
||||
}
|
||||
else if sym.kind == .map {
|
||||
res = res.replace('map_string_', 'map[string]')
|
||||
}
|
||||
// mod.submod.submod2.Type => submod2.Type
|
||||
if res.contains('.') {
|
||||
vals := res.split('.')
|
||||
if vals.len > 2 {
|
||||
res = vals[vals.len - 2] + '.' + vals[vals.len - 1]
|
||||
}
|
||||
}
|
||||
if type_is_optional(t) {
|
||||
res = '?' + res
|
||||
}
|
||||
nr_muls := type_nr_muls(t)
|
||||
if nr_muls > 0 {
|
||||
res = strings.repeat(`&`, nr_muls) + res
|
||||
}
|
||||
/*
|
||||
if res.starts_with(cur_mod +'.') {
|
||||
res = res[cur_mod.len+1.. ]
|
||||
}
|
||||
*/
|
||||
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -0,0 +1,621 @@
|
|||
module table
|
||||
|
||||
import (
|
||||
strings
|
||||
)
|
||||
|
||||
pub type Type int
|
||||
|
||||
pub type TypeInfo = Array | ArrayFixed | Map | Struct |
|
||||
MultiReturn | Alias | Enum | SumType | Fn
|
||||
|
||||
pub struct TypeSymbol {
|
||||
pub:
|
||||
parent_idx int
|
||||
mut:
|
||||
info TypeInfo
|
||||
kind Kind
|
||||
name string
|
||||
methods []Fn
|
||||
// is_sum bool
|
||||
}
|
||||
|
||||
pub enum TypeExtra {
|
||||
unset
|
||||
optional
|
||||
variadic
|
||||
}
|
||||
|
||||
pub fn (types []Type) contains(typ Type) bool {
|
||||
for t in types {
|
||||
if int(typ) == int(t) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// return underlying TypeSymbol idx
|
||||
[inline]
|
||||
pub fn type_idx(t Type) int {
|
||||
return u16(t) & 0xffff
|
||||
}
|
||||
|
||||
// return nr_muls
|
||||
[inline]
|
||||
pub fn type_nr_muls(t Type) int {
|
||||
return (int(t)>>16) & 0xff
|
||||
}
|
||||
|
||||
// return true if pointer (nr_muls>0)
|
||||
[inline]
|
||||
pub fn type_is_ptr(t Type) bool {
|
||||
return type_nr_muls(t) > 0 // || t == voidptr_type_idx
|
||||
}
|
||||
// set nr_muls on Type and return it
|
||||
[inline]
|
||||
pub fn type_set_nr_muls(t Type, nr_muls int) Type {
|
||||
if nr_muls < 0 || nr_muls > 255 {
|
||||
panic('typ_set_nr_muls: nr_muls must be between 0 & 255')
|
||||
}
|
||||
return (int(type_extra(t))<<24) | (nr_muls<<16) | u16(type_idx(t))
|
||||
}
|
||||
|
||||
// increments nr_nuls on Type and return it
|
||||
[inline]
|
||||
pub fn type_to_ptr(t Type) Type {
|
||||
nr_muls := type_nr_muls(t)
|
||||
if nr_muls == 255 {
|
||||
panic('type_to_pre: nr_muls is already at max of 255')
|
||||
}
|
||||
return (int(type_extra(t))<<24) | ((nr_muls + 1)<<16) | u16(type_idx(t))
|
||||
}
|
||||
|
||||
// decrement nr_muls on Type and return it
|
||||
[inline]
|
||||
pub fn type_deref(t Type) Type {
|
||||
nr_muls := type_nr_muls(t)
|
||||
if nr_muls == 0 {
|
||||
panic('deref: type `$t` is not a pointer')
|
||||
}
|
||||
return (int(type_extra(t))<<24) | ((nr_muls - 1)<<16) | u16(type_idx(t))
|
||||
}
|
||||
|
||||
// return extra info
|
||||
[inline]
|
||||
pub fn type_extra(t Type) TypeExtra {
|
||||
return (int(t)>>24) & 0xff
|
||||
}
|
||||
|
||||
// set extra info
|
||||
[inline]
|
||||
pub fn type_set_extra(t Type, extra TypeExtra) Type {
|
||||
return (int(extra)<<24) | (type_nr_muls(t)<<16) | u16(type_idx(t))
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn type_is_optional(t Type) bool {
|
||||
return type_extra(t) == .optional
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn type_to_optional(t Type) Type {
|
||||
return type_set_extra(t, .optional)
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn type_is_variadic(t Type) bool {
|
||||
return type_extra(t) == .variadic
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn type_to_variadic(t Type) Type {
|
||||
return type_set_extra(t, .variadic)
|
||||
}
|
||||
|
||||
// new type with idx of TypeSymbol, not pointer (nr_muls=0)
|
||||
[inline]
|
||||
pub fn new_type(idx int) Type {
|
||||
if idx < 1 || idx > 65536 {
|
||||
panic('new_type_id: idx must be between 1 & 65536')
|
||||
}
|
||||
return idx
|
||||
}
|
||||
|
||||
// return Type idx of TypeSymbol & specify if ptr (nr_muls)
|
||||
[inline]
|
||||
pub fn new_type_ptr(idx int, nr_muls int) Type {
|
||||
if idx < 1 || idx > 65536 {
|
||||
panic('typ_ptr: idx must be between 1 & 65536')
|
||||
}
|
||||
if nr_muls < 0 || nr_muls > 255 {
|
||||
panic('typ_ptr: nr_muls must be between 0 & 255')
|
||||
}
|
||||
return (nr_muls<<16) | u16(idx)
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn is_number(typ Type) bool {
|
||||
typ_sym := c.table.get_type_symbol(typ)
|
||||
return typ_sym.is_int()
|
||||
//idx := type_idx(typ)
|
||||
//return idx in [int_type_idx, byte_type_idx, u64_type_idx]
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
pub const (
|
||||
// primitive types
|
||||
void_type_idx = 1
|
||||
voidptr_type_idx = 2
|
||||
byteptr_type_idx = 3
|
||||
charptr_type_idx = 4
|
||||
i8_type_idx = 5
|
||||
i16_type_idx = 6
|
||||
int_type_idx = 7
|
||||
i64_type_idx = 8
|
||||
byte_type_idx = 9
|
||||
u16_type_idx = 10
|
||||
u32_type_idx = 11
|
||||
u64_type_idx = 12
|
||||
f32_type_idx = 13
|
||||
f64_type_idx = 14
|
||||
char_type_idx = 15
|
||||
bool_type_idx = 16
|
||||
none_type_idx = 17
|
||||
// advanced / defined from v structs
|
||||
string_type_idx = 18
|
||||
array_type_idx = 19
|
||||
map_type_idx = 20
|
||||
)
|
||||
|
||||
pub const (
|
||||
number_idxs = [int_type_idx, byte_type_idx, u16_type_idx, i16_type_idx, i64_type_idx, u32_type_idx, u64_type_idx]
|
||||
)
|
||||
|
||||
pub const (
|
||||
void_type = new_type(void_type_idx)
|
||||
voidptr_type = new_type(voidptr_type_idx)
|
||||
byteptr_type = new_type(byteptr_type_idx)
|
||||
charptr_type = new_type(charptr_type_idx)
|
||||
i8_type = new_type(i8_type_idx)
|
||||
int_type = new_type(int_type_idx)
|
||||
i16_type = new_type(i16_type_idx)
|
||||
i64_type = new_type(i64_type_idx)
|
||||
byte_type = new_type(byte_type_idx)
|
||||
u16_type = new_type(u16_type_idx)
|
||||
u32_type = new_type(u32_type_idx)
|
||||
u64_type = new_type(u64_type_idx)
|
||||
f32_type = new_type(f32_type_idx)
|
||||
f64_type = new_type(f64_type_idx)
|
||||
char_type = new_type(char_type_idx)
|
||||
bool_type = new_type(bool_type_idx)
|
||||
none_type = new_type(none_type_idx)
|
||||
string_type = new_type(string_type_idx)
|
||||
array_type = new_type(array_type_idx)
|
||||
map_type = new_type(map_type_idx)
|
||||
)
|
||||
|
||||
pub const (
|
||||
builtin_type_names = ['void', 'voidptr', 'charptr', 'byteptr', 'i8', 'i16', 'int', 'i64', 'u16', 'u32', 'u64',
|
||||
'f32', 'f64', 'string', 'char', 'byte', 'bool', 'none', 'array', 'array_fixed', 'map', 'struct',
|
||||
'mapnode', 'ustring']
|
||||
)
|
||||
|
||||
pub struct MultiReturn {
|
||||
pub:
|
||||
name string
|
||||
mut:
|
||||
types []Type
|
||||
}
|
||||
|
||||
pub enum Kind {
|
||||
placeholder
|
||||
void
|
||||
voidptr
|
||||
byteptr
|
||||
charptr
|
||||
i8
|
||||
i16
|
||||
int
|
||||
i64
|
||||
byte
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
f32
|
||||
f64
|
||||
char
|
||||
bool
|
||||
none_
|
||||
string
|
||||
array
|
||||
array_fixed
|
||||
map
|
||||
struct_
|
||||
multi_return
|
||||
sum_type
|
||||
alias
|
||||
enum_
|
||||
function
|
||||
}
|
||||
|
||||
pub fn (t &TypeSymbol) str() string {
|
||||
return t.name.replace('array_', '[]')
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) enum_info() Enum {
|
||||
match t.info {
|
||||
Enum {
|
||||
return it
|
||||
}
|
||||
else {
|
||||
panic('TypeSymbol.enum_info(): no enum info for type: $t.name')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) mr_info() MultiReturn {
|
||||
match t.info {
|
||||
MultiReturn {
|
||||
return it
|
||||
}
|
||||
else {
|
||||
panic('TypeSymbol.mr_info(): no multi return info for type: $t.name')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) array_info() Array {
|
||||
match t.info {
|
||||
Array {
|
||||
return it
|
||||
}
|
||||
else {
|
||||
panic('TypeSymbol.array_info(): no array info for type: $t.name')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) array_fixed_info() ArrayFixed {
|
||||
match t.info {
|
||||
ArrayFixed {
|
||||
return it
|
||||
}
|
||||
else {
|
||||
panic('TypeSymbol.array_fixed(): no array fixed info for type: $t.name')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) map_info() Map {
|
||||
match t.info {
|
||||
Map {
|
||||
return it
|
||||
}
|
||||
else {
|
||||
panic('TypeSymbol.map_info(): no map info for type: $t.name')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn (t TypeSymbol) str() string {
|
||||
return t.name
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
pub fn (t mut Table) register_builtin_type_symbols() {
|
||||
// reserve index 0 so nothing can go there
|
||||
// save index check, 0 will mean not found
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .placeholder
|
||||
name: 'reserved_0'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .void
|
||||
name: 'void'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .voidptr
|
||||
name: 'voidptr'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .byteptr
|
||||
name: 'byteptr'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .charptr
|
||||
name: 'charptr'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .i8
|
||||
name: 'i8'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .i16
|
||||
name: 'i16'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .int
|
||||
name: 'int'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .i64
|
||||
name: 'i64'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .byte
|
||||
name: 'byte'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .u16
|
||||
name: 'u16'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .u32
|
||||
name: 'u32'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .u64
|
||||
name: 'u64'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .f32
|
||||
name: 'f32'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .f64
|
||||
name: 'f64'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .char
|
||||
name: 'char'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .bool
|
||||
name: 'bool'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .none_
|
||||
name: 'none'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .string
|
||||
name: 'string'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .array
|
||||
name: 'array'
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .map
|
||||
name: 'map'
|
||||
})
|
||||
// TODO: remove. for v1 map compatibility
|
||||
map_string_string_idx := t.find_or_register_map(string_type, string_type)
|
||||
map_string_int_idx := t.find_or_register_map(string_type, int_type)
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .alias
|
||||
name: 'map_string'
|
||||
parent_idx: map_string_string_idx
|
||||
})
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
kind: .alias
|
||||
name: 'map_int'
|
||||
parent_idx: map_string_int_idx
|
||||
})
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) is_int() bool {
|
||||
return t.kind in [.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64]
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) is_float() bool {
|
||||
return t.kind in [.f32, .f64]
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) is_number() bool {
|
||||
return t.is_int() || t.is_float()
|
||||
}
|
||||
|
||||
pub fn (k Kind) str() string {
|
||||
k_str := match k {
|
||||
.placeholder{
|
||||
'placeholder'
|
||||
}
|
||||
.void{
|
||||
'void'
|
||||
}
|
||||
.voidptr{
|
||||
'voidptr'
|
||||
}
|
||||
.charptr{
|
||||
'charptr'
|
||||
}
|
||||
.byteptr{
|
||||
'byteptr'
|
||||
}
|
||||
.struct_{
|
||||
'struct'
|
||||
}
|
||||
.int{
|
||||
'int'
|
||||
}
|
||||
.i8{
|
||||
'i8'
|
||||
}
|
||||
.i16{
|
||||
'i16'
|
||||
}
|
||||
.i64{
|
||||
'i64'
|
||||
}
|
||||
.byte{
|
||||
'byte'
|
||||
}
|
||||
.u16{
|
||||
'u16'
|
||||
}
|
||||
.u32{
|
||||
'u32'
|
||||
}
|
||||
.u64{
|
||||
'u64'
|
||||
}
|
||||
.f32{
|
||||
'f32'
|
||||
}
|
||||
.f64{
|
||||
'f64'
|
||||
}
|
||||
.string{
|
||||
'string'
|
||||
}
|
||||
.char{
|
||||
'char'
|
||||
}
|
||||
.bool{
|
||||
'bool'
|
||||
}
|
||||
.none_{
|
||||
'none'
|
||||
}
|
||||
.array{
|
||||
'array'
|
||||
}
|
||||
.array_fixed{
|
||||
'array_fixed'
|
||||
}
|
||||
.map{
|
||||
'map'
|
||||
}
|
||||
.multi_return{
|
||||
'multi_return'
|
||||
}
|
||||
.sum_type{
|
||||
'sum_type'
|
||||
}
|
||||
.alias{
|
||||
'alias'
|
||||
}
|
||||
.enum_{
|
||||
'enum'
|
||||
}
|
||||
else {
|
||||
'unknown'}
|
||||
}
|
||||
return k_str
|
||||
}
|
||||
|
||||
pub fn (kinds []Kind) str() string {
|
||||
mut kinds_str := ''
|
||||
for i, k in kinds {
|
||||
kinds_str += k.str()
|
||||
if i < kinds.len - 1 {
|
||||
kinds_str += '_'
|
||||
}
|
||||
}
|
||||
return kinds_str
|
||||
}
|
||||
|
||||
pub struct Struct {
|
||||
pub mut:
|
||||
fields []Field
|
||||
}
|
||||
|
||||
pub struct Enum {
|
||||
pub mut:
|
||||
vals []string
|
||||
}
|
||||
|
||||
pub struct Alias {
|
||||
pub:
|
||||
foo string
|
||||
}
|
||||
|
||||
pub struct Field {
|
||||
pub:
|
||||
name string
|
||||
mut:
|
||||
typ Type
|
||||
}
|
||||
|
||||
pub struct Array {
|
||||
pub:
|
||||
nr_dims int
|
||||
mut:
|
||||
elem_type Type
|
||||
}
|
||||
|
||||
pub struct ArrayFixed {
|
||||
pub:
|
||||
nr_dims int
|
||||
size int
|
||||
mut:
|
||||
elem_type Type
|
||||
}
|
||||
|
||||
pub struct Map {
|
||||
pub mut:
|
||||
key_type Type
|
||||
value_type Type
|
||||
}
|
||||
|
||||
pub struct SumType {
|
||||
pub:
|
||||
variants []Type
|
||||
}
|
||||
|
||||
pub fn (table &Table) type_to_str(t Type) string {
|
||||
sym := table.get_type_symbol(t)
|
||||
if sym.kind == .multi_return {
|
||||
mut res := '('
|
||||
mr_info := sym.info as MultiReturn
|
||||
for i, typ in mr_info.types {
|
||||
res += table.type_to_str(typ)
|
||||
if i < mr_info.types.len - 1 {
|
||||
res += ', '
|
||||
}
|
||||
}
|
||||
res += ')'
|
||||
return res
|
||||
}
|
||||
mut res := sym.name
|
||||
if sym.kind == .array {
|
||||
res = res.replace('array_', '[]')
|
||||
}
|
||||
else if sym.kind == .map {
|
||||
res = res.replace('map_string_', 'map[string]')
|
||||
}
|
||||
// mod.submod.submod2.Type => submod2.Type
|
||||
if res.contains('.') {
|
||||
vals := res.split('.')
|
||||
if vals.len > 2 {
|
||||
res = vals[vals.len - 2] + '.' + vals[vals.len - 1]
|
||||
}
|
||||
}
|
||||
if type_is_optional(t) {
|
||||
res = '?' + res
|
||||
}
|
||||
nr_muls := type_nr_muls(t)
|
||||
if nr_muls > 0 {
|
||||
res = strings.repeat(`&`, nr_muls) + res
|
||||
}
|
||||
/*
|
||||
if res.starts_with(cur_mod +'.') {
|
||||
res = res[cur_mod.len+1.. ]
|
||||
}
|
||||
*/
|
||||
|
||||
return res
|
||||
}
|
|
@ -3,6 +3,10 @@
|
|||
// that can be found in the LICENSE file.
|
||||
module table
|
||||
|
||||
import (
|
||||
strings
|
||||
)
|
||||
|
||||
pub struct Table {
|
||||
// struct_fields map[string][]string
|
||||
pub mut:
|
||||
|
|
|
@ -1,153 +0,0 @@
|
|||
module table
|
||||
|
||||
pub type Type int
|
||||
|
||||
pub enum TypeExtra {
|
||||
unset
|
||||
optional
|
||||
variadic
|
||||
}
|
||||
|
||||
pub fn (types []Type) contains(typ Type) bool {
|
||||
for t in types {
|
||||
if int(typ) == int(t) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// return underlying TypeSymbol idx
|
||||
[inline]
|
||||
pub fn type_idx(t Type) int {
|
||||
return u16(t) & 0xffff
|
||||
}
|
||||
|
||||
// return nr_muls
|
||||
[inline]
|
||||
pub fn type_nr_muls(t Type) int {
|
||||
return (int(t)>>16) & 0xff
|
||||
}
|
||||
|
||||
// return true if pointer (nr_muls>0)
|
||||
[inline]
|
||||
pub fn type_is_ptr(t Type) bool {
|
||||
return type_nr_muls(t) > 0 // || t == voidptr_type_idx
|
||||
}
|
||||
// set nr_muls on Type and return it
|
||||
[inline]
|
||||
pub fn type_set_nr_muls(t Type, nr_muls int) Type {
|
||||
if nr_muls < 0 || nr_muls > 255 {
|
||||
panic('typ_set_nr_muls: nr_muls must be between 0 & 255')
|
||||
}
|
||||
return (int(type_extra(t))<<24) | (nr_muls<<16) | u16(type_idx(t))
|
||||
}
|
||||
|
||||
// increments nr_nuls on Type and return it
|
||||
[inline]
|
||||
pub fn type_to_ptr(t Type) Type {
|
||||
nr_muls := type_nr_muls(t)
|
||||
if nr_muls == 255 {
|
||||
panic('type_to_pre: nr_muls is already at max of 255')
|
||||
}
|
||||
return (int(type_extra(t))<<24) | ((nr_muls + 1)<<16) | u16(type_idx(t))
|
||||
}
|
||||
|
||||
// decrement nr_muls on Type and return it
|
||||
[inline]
|
||||
pub fn type_deref(t Type) Type {
|
||||
nr_muls := type_nr_muls(t)
|
||||
if nr_muls == 0 {
|
||||
panic('deref: type `$t` is not a pointer')
|
||||
}
|
||||
return (int(type_extra(t))<<24) | ((nr_muls - 1)<<16) | u16(type_idx(t))
|
||||
}
|
||||
|
||||
// return extra info
|
||||
[inline]
|
||||
pub fn type_extra(t Type) TypeExtra {
|
||||
return (int(t)>>24) & 0xff
|
||||
}
|
||||
|
||||
// set extra info
|
||||
[inline]
|
||||
pub fn type_set_extra(t Type, extra TypeExtra) Type {
|
||||
return (int(extra)<<24) | (type_nr_muls(t)<<16) | u16(type_idx(t))
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn type_is_optional(t Type) bool {
|
||||
return type_extra(t) == .optional
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn type_to_optional(t Type) Type {
|
||||
return type_set_extra(t, .optional)
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn type_is_variadic(t Type) bool {
|
||||
return type_extra(t) == .variadic
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn type_to_variadic(t Type) Type {
|
||||
return type_set_extra(t, .variadic)
|
||||
}
|
||||
|
||||
// new type with idx of TypeSymbol, not pointer (nr_muls=0)
|
||||
[inline]
|
||||
pub fn new_type(idx int) Type {
|
||||
if idx < 1 || idx > 65536 {
|
||||
panic('new_type_id: idx must be between 1 & 65536')
|
||||
}
|
||||
return idx
|
||||
}
|
||||
|
||||
// return Type idx of TypeSymbol & specify if ptr (nr_muls)
|
||||
[inline]
|
||||
pub fn new_type_ptr(idx int, nr_muls int) Type {
|
||||
if idx < 1 || idx > 65536 {
|
||||
panic('typ_ptr: idx must be between 1 & 65536')
|
||||
}
|
||||
if nr_muls < 0 || nr_muls > 255 {
|
||||
panic('typ_ptr: nr_muls must be between 0 & 255')
|
||||
}
|
||||
return (nr_muls<<16) | u16(idx)
|
||||
}
|
||||
|
||||
pub const (
|
||||
number_idxs = [int_type_idx, byte_type_idx, u16_type_idx, i16_type_idx, i64_type_idx, u32_type_idx, u64_type_idx]
|
||||
)
|
||||
/*
|
||||
pub fn is_number(typ Type) bool {
|
||||
typ_sym := c.table.get_type_symbol(typ)
|
||||
return typ_sym.is_int()
|
||||
//idx := type_idx(typ)
|
||||
//return idx in [int_type_idx, byte_type_idx, u64_type_idx]
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
pub const (
|
||||
void_type = new_type(void_type_idx)
|
||||
voidptr_type = new_type(voidptr_type_idx)
|
||||
byteptr_type = new_type(byteptr_type_idx)
|
||||
charptr_type = new_type(charptr_type_idx)
|
||||
i8_type = new_type(i8_type_idx)
|
||||
int_type = new_type(int_type_idx)
|
||||
i16_type = new_type(i16_type_idx)
|
||||
i64_type = new_type(i64_type_idx)
|
||||
byte_type = new_type(byte_type_idx)
|
||||
u16_type = new_type(u16_type_idx)
|
||||
u32_type = new_type(u32_type_idx)
|
||||
u64_type = new_type(u64_type_idx)
|
||||
f32_type = new_type(f32_type_idx)
|
||||
f64_type = new_type(f64_type_idx)
|
||||
char_type = new_type(char_type_idx)
|
||||
bool_type = new_type(bool_type_idx)
|
||||
none_type = new_type(none_type_idx)
|
||||
string_type = new_type(string_type_idx)
|
||||
array_type = new_type(array_type_idx)
|
||||
map_type = new_type(map_type_idx)
|
||||
)
|
|
@ -0,0 +1,48 @@
|
|||
import os
|
||||
import term
|
||||
|
||||
fn test_all() {
|
||||
files := os.ls('.') or {
|
||||
panic(err)
|
||||
}
|
||||
for file in files {
|
||||
if !file.ends_with('.vv') {
|
||||
continue
|
||||
}
|
||||
print(file + ' ')
|
||||
program := file.replace('.vv', '.v')
|
||||
os.cp(file, program) or {
|
||||
panic(err)
|
||||
}
|
||||
os.rm('exe')
|
||||
x := os.exec('v -o exe -cflags "-w" -cg -backend experimental $program') or {
|
||||
panic(err)
|
||||
}
|
||||
println(x.output.limit(30))
|
||||
os.rm(program)
|
||||
res := os.exec('./exe') or {
|
||||
println('nope')
|
||||
panic(err)
|
||||
}
|
||||
// println('============')
|
||||
// println(res.output)
|
||||
// println('============')
|
||||
mut expected := os.read_file(program.replace('.v', '') + '.out') or {
|
||||
panic(err)
|
||||
}
|
||||
expected = expected.trim_space()
|
||||
found := res.output.trim_space()
|
||||
if expected != found {
|
||||
println(term.red('FAIL'))
|
||||
println('============')
|
||||
println('expected:')
|
||||
println(expected)
|
||||
println('\nfound:')
|
||||
println(found)
|
||||
println('============')
|
||||
}
|
||||
else {
|
||||
println(term.green('OK'))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
hello world
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
println('hello world')
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
Hello, game developers!
|
||||
Hello, web developers!
|
||||
Hello, tools developers!
|
||||
Hello, science developers!
|
||||
Hello, systems developers!
|
||||
Hello, embedded developers!
|
|
@ -0,0 +1,7 @@
|
|||
fn main() {
|
||||
areas := ['game', 'web', 'tools', 'science', 'systems', 'embedded']
|
||||
for i :=0;i<areas.len; i++{
|
||||
area:=areas[i]
|
||||
println('Hello, $area developers!')
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
compiler_test.v
|
|
@ -0,0 +1,10 @@
|
|||
import os
|
||||
|
||||
fn main() {
|
||||
files := os.ls('.') or { panic(err) }
|
||||
for file in files {
|
||||
if file.ends_with('_test.v') {
|
||||
println(file)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -427,46 +427,6 @@ pub fn (tok Token) is_unary() bool {
|
|||
.plus, .minus, .not, .bit_not, .mul, .amp]
|
||||
}
|
||||
|
||||
/*
|
||||
// NOTE: do we need this for all tokens (is_left_assoc / is_right_assoc),
|
||||
// or only ones with the same precedence?
|
||||
// is_left_assoc returns true if the token is left associative
|
||||
pub fn (tok Token) is_left_assoc() bool {
|
||||
return tok.kind in [
|
||||
// `.`
|
||||
.dot,
|
||||
// `+` | `-`
|
||||
.plus, .minus, // additive
|
||||
// .number,
|
||||
// `++` | `--`
|
||||
.inc, .dec,
|
||||
// `*` | `/` | `%`
|
||||
.mul, .div, .mod,
|
||||
// `^` | `||` | `&`
|
||||
.xor, .logical_or, .and,
|
||||
// `==` | `!=`
|
||||
.eq, .ne,
|
||||
// `<` | `<=` | `>` | `>=`
|
||||
.lt, .le, .gt, .ge, .ne, .eq,
|
||||
// `,`
|
||||
.comma]
|
||||
}
|
||||
|
||||
// is_right_assoc returns true if the token is right associative
|
||||
pub fn (tok Token) is_right_assoc() bool {
|
||||
return tok.kind in [
|
||||
// `+` | `-` | `!`
|
||||
.plus, .minus, .not, // unary
|
||||
// `=` | `+=` | `-=` | `*=` | `/=`
|
||||
.assign, .plus_assign, .minus_assign, .mult_assign, .div_assign,
|
||||
// `%=` | `>>=` | `<<=`
|
||||
.mod_assign, .right_shift_assign, .left_shift_assign,
|
||||
// `&=` | `^=` | `|=`
|
||||
.and_assign, .xor_assign, .or_assign]
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
pub fn (tok Kind) is_relational() bool {
|
||||
return tok in [
|
||||
// `<` | `<=` | `>` | `>=`
|
||||
|
|
Loading…
Reference in New Issue