Compare commits

..

No commits in common. "b81f06e3699dbb1aca577876c13031394de22182" and "9d764cd25e5aeab80e8d74c0cdbb25bfa4761924" have entirely different histories.

74 changed files with 241 additions and 1142 deletions

View File

@ -61,7 +61,9 @@ fn main() {
if term_colors {
os.setenv('VCOLORS', 'always', true)
}
foptions.vlog('vfmt foptions: $foptions')
if foptions.is_verbose {
eprintln('vfmt foptions: $foptions')
}
if foptions.is_worker {
// -worker should be added by a parent vfmt process.
// We launch a sub process for each file because
@ -107,7 +109,9 @@ fn main() {
mut worker_command_array := cli_args_no_files.clone()
worker_command_array << ['-worker', util.quote_path(fpath)]
worker_cmd := worker_command_array.join(' ')
foptions.vlog('vfmt worker_cmd: $worker_cmd')
if foptions.is_verbose {
eprintln('vfmt worker_cmd: $worker_cmd')
}
worker_result := os.execute(worker_cmd)
// Guard against a possibly crashing worker process.
if worker_result.exit_code != 0 {
@ -147,43 +151,43 @@ fn main() {
}
}
fn setup_preferences_and_table() (&pref.Preferences, &ast.Table) {
table := ast.new_table()
fn (foptions &FormatOptions) format_file(file string) {
mut prefs := pref.new_preferences()
prefs.is_fmt = true
prefs.skip_warnings = true
return prefs, table
}
fn (foptions &FormatOptions) vlog(msg string) {
if foptions.is_verbose {
eprintln(msg)
eprintln('vfmt2 running fmt.fmt over file: $file')
}
}
fn (foptions &FormatOptions) format_file(file string) {
foptions.vlog('vfmt2 running fmt.fmt over file: $file')
prefs, table := setup_preferences_and_table()
table := ast.new_table()
// checker := checker.new_checker(table, prefs)
file_ast := parser.parse_file(file, table, .parse_comments, prefs)
// checker.new_checker(table, prefs).check(file_ast)
// checker.check(file_ast)
formatted_content := fmt.fmt(file_ast, table, prefs, foptions.is_debug)
file_name := os.file_name(file)
ulid := rand.ulid()
vfmt_output_path := os.join_path(vtmp_folder, 'vfmt_${ulid}_$file_name')
os.write_file(vfmt_output_path, formatted_content) or { panic(err) }
foptions.vlog('fmt.fmt worked and $formatted_content.len bytes were written to $vfmt_output_path .')
if foptions.is_verbose {
eprintln('fmt.fmt worked and $formatted_content.len bytes were written to $vfmt_output_path .')
}
eprintln('$formatted_file_token$vfmt_output_path')
}
fn (foptions &FormatOptions) format_pipe() {
foptions.vlog('vfmt2 running fmt.fmt over stdin')
prefs, table := setup_preferences_and_table()
mut prefs := pref.new_preferences()
prefs.is_fmt = true
if foptions.is_verbose {
eprintln('vfmt2 running fmt.fmt over stdin')
}
input_text := os.get_raw_lines_joined()
table := ast.new_table()
// checker := checker.new_checker(table, prefs)
file_ast := parser.parse_text(input_text, '', table, .parse_comments, prefs)
// checker.new_checker(table, prefs).check(file_ast)
// checker.check(file_ast)
formatted_content := fmt.fmt(file_ast, table, prefs, foptions.is_debug)
print(formatted_content)
foptions.vlog('fmt.fmt worked and $formatted_content.len bytes were written to stdout.')
if foptions.is_verbose {
eprintln('fmt.fmt worked and $formatted_content.len bytes were written to stdout.')
}
}
fn print_compiler_options(compiler_params &pref.Preferences) {
@ -230,7 +234,9 @@ fn (mut foptions FormatOptions) post_process_file(file string, formatted_file_pa
return
}
diff_cmd := foptions.find_diff_cmd()
foptions.vlog('Using diff command: $diff_cmd')
if foptions.is_verbose {
eprintln('Using diff command: $diff_cmd')
}
diff := diff.color_compare_files(diff_cmd, file, formatted_file_path)
if diff.len > 0 {
println(diff)

View File

@ -49,26 +49,17 @@ enum RunCommandKind {
const expect_nothing = '<nothing>'
const starts_with_nothing = '<nothing>'
const ends_with_nothing = '<nothing>'
const contains_nothing = '<nothing>'
struct Command {
mut:
line string
label string // when set, the label will be printed *before* cmd.line is executed
ecode int
okmsg string
errmsg string
rmfile string
runcmd RunCommandKind = .system
expect string = expect_nothing
starts_with string = starts_with_nothing
ends_with string = ends_with_nothing
contains string = contains_nothing
output string
line string
label string // when set, the label will be printed *before* cmd.line is executed
ecode int
okmsg string
errmsg string
rmfile string
runcmd RunCommandKind = .system
expect string = expect_nothing
output string
}
fn get_all_commands() []Command {
@ -108,14 +99,6 @@ fn get_all_commands() []Command {
runcmd: .execute
expect: 'Hello, World!\n'
}
res << Command{
line: '$vexe interpret examples/hanoi.v'
okmsg: 'V can interpret hanoi.v'
runcmd: .execute
starts_with: 'Disc 1 from A to C...\n'
ends_with: 'Disc 1 from A to C...\n'
contains: 'Disc 7 from A to C...\n'
}
res << Command{
line: '$vexe -o - examples/hello_world.v | grep "#define V_COMMIT_HASH" > /dev/null'
okmsg: 'V prints the generated source code to stdout with `-o -` .'
@ -269,56 +252,23 @@ fn (mut cmd Command) run() {
spent := sw.elapsed().milliseconds()
//
mut is_failed := false
mut is_failed_expected := false
mut is_failed_starts_with := false
mut is_failed_ends_with := false
mut is_failed_contains := false
if cmd.ecode != 0 {
is_failed = true
}
if cmd.expect != expect_nothing {
if cmd.output != cmd.expect {
is_failed = true
is_failed_expected = true
}
}
if cmd.starts_with != starts_with_nothing {
if !cmd.output.starts_with(cmd.starts_with) {
is_failed = true
is_failed_starts_with = true
}
}
if cmd.ends_with != ends_with_nothing {
if !cmd.output.ends_with(cmd.ends_with) {
is_failed = true
is_failed_ends_with = true
}
}
if cmd.contains != contains_nothing {
if !cmd.output.contains(cmd.contains) {
is_failed = true
is_failed_contains = true
}
}
//
run_label := if is_failed { term.failed('FAILED') } else { term_highlight('OK') }
println('> Running: "$cmd.line" took: $spent ms ... $run_label')
//
if is_failed && is_failed_expected {
eprintln('> expected:\n$cmd.expect')
eprintln('> output:\n$cmd.output')
}
if is_failed && is_failed_starts_with {
eprintln('> expected to start with:\n$cmd.starts_with')
eprintln('> output:\n${cmd.output#[..cmd.starts_with.len]}')
}
if is_failed && is_failed_ends_with {
eprintln('> expected to end with:\n$cmd.ends_with')
eprintln('> output:\n${cmd.output#[-cmd.starts_with.len..]}')
}
if is_failed && is_failed_contains {
eprintln('> expected to contain:\n$cmd.contains')
eprintln('> output:\n$cmd.output')
if is_failed && cmd.expect != expect_nothing {
if cmd.output != cmd.expect {
eprintln('> expected:\n$cmd.expect')
eprintln('> output:\n$cmd.output')
}
}
if vtest_nocleanup {
return

View File

@ -1,18 +1,3 @@
fn main() {
graph := {
'A': ['B', 'C']
'B': ['A', 'D', 'E']
'C': ['A', 'F']
'D': ['B']
'E': ['B', 'F']
'F': ['C', 'E']
}
println('Graph: $graph')
path := breadth_first_search_path(graph, 'A', 'F')
println('The shortest path from node A to node F is: $path')
assert path == ['A', 'C', 'F']
}
// Breadth-First Search (BFS) allows you to find the shortest distance between two nodes in the graph.
fn breadth_first_search_path(graph map[string][]string, vertex string, target string) []string {
mut path := []string{}
@ -39,3 +24,18 @@ fn breadth_first_search_path(graph map[string][]string, vertex string, target st
}
return path
}
fn main() {
graph := {
'A': ['B', 'C']
'B': ['A', 'D', 'E']
'C': ['A', 'F']
'D': ['B']
'E': ['B', 'F']
'F': ['C', 'E']
}
println('Graph: $graph')
path := breadth_first_search_path(graph, 'A', 'F')
println('The shortest path from node A to node F is: $path')
assert path == ['A', 'C', 'F']
}

View File

@ -32,7 +32,8 @@ const (
struct App {
minutes_tic []f32 = [f32(center - tw), tp, center + tw, tp, center + tw, tp, center + tw,
tp + 1 * th, center - tw, tp + 1 * th]
tp +
1 * th, center - tw, tp + 1 * th]
hours_tic []f32 = [f32(center - tw), tp, center + tw, tp, center + tw, tp, center + tw, tp + 2 * th,
center - tw, tp + 2 * th]
hours3_tic []f32 = [f32(center - tw), tp, center + tw, tp, center + tw, tp, center + tw, tp + 3 * th,

View File

@ -1,92 +0,0 @@
// Author: ccs
// I follow literally code in C, done many years ago
fn main() {
// Adjacency matrix as a map
graph := {
'A': ['B', 'C']
'B': ['A', 'D', 'E']
'C': ['A', 'F']
'D': ['B']
'E': ['B', 'F']
'F': ['C', 'E']
}
println('Graph: $graph')
path := breadth_first_search_path(graph, 'A', 'F')
println('\n The shortest path from node A to node F is: $path.reverse()')
}
// Breadth-First Search (BFS) allows you to find the shortest distance between two nodes in the graph.
fn breadth_first_search_path(graph map[string][]string, start string, target string) []string {
mut path := []string{} // ONE PATH with SUCCESS = array
mut queue := []string{} // a queue ... many paths
// all_nodes := graph.keys() // get a key of this map
n_nodes := graph.len // numbers of nodes of this graph
// a map to store all the nodes visited to avoid cycles
// start all them with False, not visited yet
mut visited := a_map_nodes_bool(n_nodes) // a map fully
// false ==> not visited yet: {'A': false, 'B': false, 'C': false, 'D': false, 'E': false}
queue << start // first arrival
for queue.len != 0 {
mut node := departure(mut queue) // get the front node and remove it
if visited[node] == false { // check if this node is already visited
// if no ... test it searchinf for a final node
visited[node] = true // means: visit this node
if node == target {
path = build_path_reverse(graph, start, node, visited)
return path
}
// Expansion of node removed from queue
print('\n Expansion of node $node (true/false): ${graph[node]}')
// take all nodes from the node
for vertex in graph[node] { // println("\n ...${vertex}")
// not explored yet
if visited[vertex] == false {
queue << vertex
}
}
print('\n QUEUE: $queue (only not visited) \n Visited: $visited')
}
}
path = ['Path not found, problem in the Graph, start or end nodes! ']
return path
}
// Creating a map for VISITED nodes ...
// starting by false ===> means this node was not visited yet
fn a_map_nodes_bool(size int) map[string]bool {
mut my_map := map[string]bool{} // look this map ...
base := u8(65)
mut key := base.ascii_str()
for i in 0 .. size {
key = u8(base + i).ascii_str()
my_map[key] = false
}
return my_map
}
// classical removing of a node from the start of a queue
fn departure(mut queue []string) string {
mut x := queue[0]
queue.delete(0)
return x
}
// Based in the current node that is final, search for its parent, already visited, up to the root or start node
fn build_path_reverse(graph map[string][]string, start string, final string, visited map[string]bool) []string {
print('\n\n Nodes visited (true) or no (false): $visited')
array_of_nodes := graph.keys()
mut current := final
mut path := []string{}
path << current
for (current != start) {
for i in array_of_nodes {
if (current in graph[i]) && (visited[i] == true) {
current = i
break // the first ocurrence is enough
}
}
path << current // update the path tracked
}
return path
}

View File

@ -1,103 +0,0 @@
// Author: ccs
// I follow literally code in C, done many years ago
fn main() {
// Adjacency matrix as a map
// Example 01
graph_01 := {
'A': ['B', 'C']
'B': ['A', 'D', 'E']
'C': ['A', 'F']
'D': ['B']
'E': ['F', 'B', 'F']
'F': ['C', 'E']
}
// Example 02
graph_02 := {
'A': ['B', 'C', 'D']
'B': ['E']
'C': ['F']
'D': ['E']
'E': ['H']
'F': ['H']
'G': ['H']
'H': ['E', 'F', 'G']
}
// println('Graph: $graph')
path_01 := depth_first_search_path(graph_01, 'A', 'F')
println('\n Graph_01: a first path from node A to node F is: $path_01.reverse()')
path_02 := depth_first_search_path(graph_02, 'A', 'H')
println('\n Graph_02: a first path from node A to node F is: $path_02.reverse()')
}
// Depth-First Search (BFS) allows you to find a path between two nodes in the graph.
fn depth_first_search_path(graph map[string][]string, start string, target string) []string {
mut path := []string{} // ONE PATH with SUCCESS = array
mut stack := []string{} // a stack ... many nodes
// all_nodes := graph.keys() // get a key of this map
n_nodes := graph.len // numbers of nodes of this graph
mut visited := a_map_nodes_bool(n_nodes) // a map fully
// false ... not visited yet: {'A': false, 'B': false, 'C': false, 'D': false, 'E': false}
stack << start // first push on the stack
for stack.len > 0 {
mut node := stack.pop() // get the top node and remove it from the stack
// check if this node is already visited
if visited[node] == false {
// if no ... test it searchin for a final node
visited[node] = true // means: node visited
if node == target {
path = build_path_reverse(graph, start, node, visited)
return path
}
// Exploring of node removed from stack and add its relatives
print('\n Exploring of node $node (true/false): ${graph[node]}')
// graph[node].reverse() take a classical choice for DFS
// at most os left in this case.
// use vertex in graph[node] the choice is right
// take all nodes from the node
for vertex in graph[node].reverse() {
// println("\n ...${vertex}")
// not explored yet
if visited[vertex] == false {
stack << vertex
}
}
print('\n Stack: $stack (only not visited) \n Visited: $visited')
}
}
path = ['Path not found, problem in the Graph, start or end nodes! ']
return path
}
// Creating a map for nodes not VISITED visited ...
// starting by false ===> means this node was not visited yet
fn a_map_nodes_bool(size int) map[string]bool {
mut my_map := map[string]bool{} // look this map ...
for i in 0 .. size {
my_map[u8(65 + i).ascii_str()] = false
}
return my_map
}
// Based in the current node that is final, search for his parent, that is already visited, up to the root or start node
fn build_path_reverse(graph map[string][]string, start string, final string, visited map[string]bool) []string {
print('\n\n Nodes visited (true) or no (false): $visited')
array_of_nodes := graph.keys()
mut current := final
mut path := []string{}
path << current
for current != start {
for i in array_of_nodes {
if (current in graph[i]) && (visited[i] == true) {
current = i
break // the first ocurrence is enough
}
}
path << current // updating the path tracked
}
return path
}

View File

@ -931,7 +931,7 @@ fn test_u64_keys() {
m[i]++
assert m[i] == i + 1
}
assert u64(m.len) == end
assert m.len == end
keys := m.keys()
for i in u64(0) .. end {
assert keys[i] == i

View File

@ -919,7 +919,7 @@ fn test_u64_keys() {
m[i]++
assert m[i] == i + 1
}
assert u64(m.len) == end
assert m.len == end
keys := m.keys()
for i in u64(0) .. end {
assert keys[i] == i

View File

@ -28,7 +28,6 @@ fn help_cmd() Command {
}
}
// print_help_for_command outputs the help message of `help_cmd`.
pub fn print_help_for_command(help_cmd Command) ? {
if help_cmd.args.len > 0 {
mut cmd := help_cmd.parent
@ -55,7 +54,6 @@ pub fn print_help_for_command(help_cmd Command) ? {
}
}
// help_message returns a generated help message as a `string` for the `Command`.
pub fn (cmd Command) help_message() string {
mut help := ''
help += 'Usage: $cmd.full_name()'

View File

@ -51,7 +51,8 @@ const (
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd],
'Test With Truncation'.bytes(), 'Test Using Larger Than Block-Size Key - Hash Key First'.bytes(),
'Test With Truncation'.bytes(),
'Test Using Larger Than Block-Size Key - Hash Key First'.bytes(),
'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data'.bytes()]
)

View File

@ -278,114 +278,72 @@ pub fn (ctx &Context) draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius
// `x`,`y` is the top-left corner of the rectangle.
// `w` is the width, `h` is the height .
// `radius` is the radius of the corner-rounding in pixels.
// `c` is the color of the filled.
// `c` is the color of the outline.
pub fn (ctx &Context) draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radius f32, c gx.Color) {
assert w > 0 && h > 0 && radius >= 0
if c.a != 255 {
sgl.load_pipeline(ctx.timage_pip)
}
sgl.c4b(c.r, c.g, c.b, c.a)
sgl.begin_triangle_strip()
mut theta := f32(0)
mut xx := f32(0)
mut yy := f32(0)
mut radians := f32(0)
mut new_radius := radius
if w >= h && radius > h / 2 {
new_radius = h / 2
} else if radius > w / 2 {
new_radius = w / 2
}
r := new_radius * ctx.scale
r := radius * ctx.scale
nx := x * ctx.scale
ny := y * ctx.scale
width := w * ctx.scale
height := h * ctx.scale
// left top quarter
sgl.begin_triangle_strip()
ltx := nx + r
lty := ny + r
for i in 0 .. 91 {
if r == 0 {
break
}
radians = f32(math.radians(i))
xx = r * math.cosf(radians)
yy = r * math.sinf(radians)
sgl.v2f(ltx - xx, lty - yy)
sgl.v2f(ltx, lty)
segments := 2 * math.pi * r
segdiv := segments / 4
rb := 0
lb := int(rb + segdiv)
lt := int(lb + segdiv)
rt := int(lt + segdiv)
// left top
lx := nx + r
ly := ny + r
for i in lt .. rt {
theta = 2 * f32(math.pi) * f32(i) / segments
xx = r * math.cosf(theta)
yy = r * math.sinf(theta)
sgl.v2f(xx + lx, yy + ly)
sgl.v2f(lx, ly)
}
sgl.end()
// right top quarter
sgl.begin_triangle_strip()
rtx := nx + width - r
rty := ny + r
for i in 0 .. 91 {
if r == 0 {
break
}
radians = f32(math.radians(i))
xx = r * math.cosf(radians)
yy = r * math.sinf(radians)
sgl.v2f(rtx + xx, rty - yy)
sgl.v2f(rtx, rty)
// right top
mut rx := nx + width - r
mut ry := ny + r
for i in rt .. int(segments) {
theta = 2 * f32(math.pi) * f32(i) / segments
xx = r * math.cosf(theta)
yy = r * math.sinf(theta)
sgl.v2f(xx + rx, yy + ry)
sgl.v2f(rx, ry)
}
sgl.end()
// right bottom quarter
sgl.begin_triangle_strip()
rbx := nx + width - r
rby := ny + height - r
for i in 0 .. 91 {
if r == 0 {
break
}
radians = f32(math.radians(i))
xx = r * math.cosf(radians)
yy = r * math.sinf(radians)
sgl.v2f(rbx + xx, rby + yy)
// right bottom
mut rbx := rx
mut rby := ny + height - r
for i in rb .. lb {
theta = 2 * f32(math.pi) * f32(i) / segments
xx = r * math.cosf(theta)
yy = r * math.sinf(theta)
sgl.v2f(xx + rbx, yy + rby)
sgl.v2f(rbx, rby)
}
sgl.end()
// left bottom quarter
sgl.begin_triangle_strip()
lbx := nx + r
lby := ny + height - r
for i in 0 .. 91 {
if r == 0 {
break
}
radians = f32(math.radians(i))
xx = r * math.cosf(radians)
yy = r * math.sinf(radians)
sgl.v2f(lbx - xx, lby + yy)
// left bottom
mut lbx := lx
mut lby := ny + height - r
for i in lb .. lt {
theta = 2 * f32(math.pi) * f32(i) / segments
xx = r * math.cosf(theta)
yy = r * math.sinf(theta)
sgl.v2f(xx + lbx, yy + lby)
sgl.v2f(lbx, lby)
}
sgl.v2f(lx + xx, ly)
sgl.v2f(lx, ly)
sgl.end()
// Separate drawing is to prevent transparent color overlap
// top rectangle
sgl.begin_quads()
sgl.v2f(ltx, ny)
sgl.v2f(rtx, ny)
sgl.v2f(rtx, rty)
sgl.v2f(ltx, lty)
sgl.end()
// middle rectangle
sgl.begin_quads()
sgl.v2f(nx, ny + r)
sgl.v2f(rtx + r, rty)
sgl.v2f(rbx + r, rby)
sgl.v2f(nx, lby)
sgl.end()
// bottom rectangle
sgl.begin_quads()
sgl.v2f(lbx, lby)
sgl.v2f(lx, ly)
sgl.v2f(rx, ry)
sgl.v2f(rbx, rby)
sgl.v2f(rbx, ny + height)
sgl.v2f(lbx, ny + height)
sgl.v2f(lbx, lby)
sgl.end()
}

View File

@ -242,7 +242,8 @@ const (
cookie: [&http.Cookie{
name: 'cookie-1'
value: 'v1'
}, &http.Cookie{
},
&http.Cookie{
name: 'cookie-2'
value: 'v2'
},
@ -293,7 +294,8 @@ const (
header: {
'Set-Cookie': ['ASP.NET_SessionId=foo; path=/; HttpOnly']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'ASP.NET_SessionId'
value: 'foo'
path: '/'
@ -305,7 +307,8 @@ const (
header: {
'Set-Cookie': ['samesitedefault=foo; SameSite']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'samesitedefault'
value: 'foo'
same_site: .same_site_default_mode
@ -316,7 +319,8 @@ const (
header: {
'Set-Cookie': ['samesitelax=foo; SameSite=Lax']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'samesitelax'
value: 'foo'
same_site: .same_site_lax_mode
@ -327,7 +331,8 @@ const (
header: {
'Set-Cookie': ['samesitestrict=foo; SameSite=Strict']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'samesitestrict'
value: 'foo'
same_site: .same_site_strict_mode
@ -338,7 +343,8 @@ const (
header: {
'Set-Cookie': ['samesitenone=foo; SameSite=None']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'samesitenone'
value: 'foo'
same_site: .same_site_none_mode
@ -351,7 +357,8 @@ const (
header: {
'Set-Cookie': ['special-1=a z']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'special-1'
value: 'a z'
raw: 'special-1=a z'
@ -361,7 +368,8 @@ const (
header: {
'Set-Cookie': ['special-2=" z"']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'special-2'
value: ' z'
raw: 'special-2=" z"'
@ -371,7 +379,8 @@ const (
header: {
'Set-Cookie': ['special-3="a "']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'special-3'
value: 'a '
raw: 'special-3="a "'
@ -381,7 +390,8 @@ const (
header: {
'Set-Cookie': ['special-4=" "']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'special-4'
value: ' '
raw: 'special-4=" "'
@ -391,7 +401,8 @@ const (
header: {
'Set-Cookie': ['special-5=a,z']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'special-5'
value: 'a,z'
raw: 'special-5=a,z'
@ -401,7 +412,8 @@ const (
header: {
'Set-Cookie': ['special-6=",z"']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'special-6'
value: ',z'
raw: 'special-6=",z"'
@ -411,7 +423,8 @@ const (
header: {
'Set-Cookie': ['special-7=","']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'special-7'
value: ','
raw: 'special-8=","'

View File

@ -223,7 +223,7 @@ pub fn (mut ws Client) parse_frame_header() ?Frame {
buffer[bytes_read] = rbuff[0]
bytes_read++
// parses the first two header bytes to get basic frame information
if bytes_read == websocket.header_len_offset {
if bytes_read == u64(websocket.header_len_offset) {
frame.fin = (buffer[0] & 0x80) == 0x80
frame.rsv1 = (buffer[0] & 0x40) == 0x40
frame.rsv2 = (buffer[0] & 0x20) == 0x20
@ -249,7 +249,7 @@ pub fn (mut ws Client) parse_frame_header() ?Frame {
break
}
}
if frame.payload_len == 126 && bytes_read == websocket.extended_payload16_end_byte {
if frame.payload_len == 126 && bytes_read == u64(websocket.extended_payload16_end_byte) {
frame.header_len += 2
frame.payload_len = 0
frame.payload_len |= int(u32(buffer[2]) << 8)
@ -259,7 +259,7 @@ pub fn (mut ws Client) parse_frame_header() ?Frame {
break
}
}
if frame.payload_len == 127 && bytes_read == websocket.extended_payload64_end_byte {
if frame.payload_len == 127 && bytes_read == u64(websocket.extended_payload64_end_byte) {
frame.header_len += 8
// these shift operators needs 64 bit on clang with -prod flag
mut payload_len := u64(0)

View File

@ -162,7 +162,6 @@ pub fn rmdir_all(path string) ? {
}
// is_dir_empty will return a `bool` whether or not `path` is empty.
// Note that it will return `true` if `path` does not exist.
[manualfree]
pub fn is_dir_empty(path string) bool {
items := ls(path) or { return true }

View File

@ -41,7 +41,7 @@ fn test_open_file() {
mut file := os.open_file(filename, 'w+', 0o666) or { panic(err) }
file.write_string(hello) or { panic(err) }
file.close()
assert u64(hello.len) == os.file_size(filename)
assert hello.len == os.file_size(filename)
read_hello := os.read_file(filename) or { panic('error reading file $filename') }
assert hello == read_hello
os.rm(filename) or { panic(err) }
@ -58,7 +58,7 @@ fn test_open_file_binary() {
bytes := hello.bytes()
unsafe { file.write_ptr(bytes.data, bytes.len) }
file.close()
assert u64(hello.len) == os.file_size(filename)
assert hello.len == os.file_size(filename)
read_hello := os.read_bytes(filename) or { panic('error reading file $filename') }
assert bytes == read_hello
os.rm(filename) or { panic(err) }
@ -100,7 +100,7 @@ fn test_create_file() ? {
filename := './test1.txt'
hello := 'hello world!'
create_and_write_to_file(filename, hello) ?
assert u64(hello.len) == os.file_size(filename)
assert hello.len == os.file_size(filename)
os.rm(filename) or { panic(err) }
}
@ -138,7 +138,7 @@ fn test_write_and_read_string_to_file() {
filename := './test1.txt'
hello := 'hello world!'
os.write_file(filename, hello) or { panic(err) }
assert u64(hello.len) == os.file_size(filename)
assert hello.len == os.file_size(filename)
read_hello := os.read_file(filename) or { panic('error reading file $filename') }
assert hello == read_hello
os.rm(filename) or { panic(err) }
@ -157,7 +157,7 @@ fn test_write_and_read_bytes() {
// compare the length of the array with the file size (have to match).
unsafe { file_write.write_ptr(payload.data, 5) }
file_write.close()
assert u64(payload.len) == os.file_size(file_name)
assert payload.len == os.file_size(file_name)
mut file_read := os.open(os.real_path(file_name)) or {
eprintln('failed to open file $file_name')
return
@ -355,12 +355,6 @@ fn test_mv() {
assert !os.is_dir(expected)
}
fn test_is_dir_empty() {
// Test that is_dir_empty returns true on
// non-existent directories ***as stated in it's doc string***
assert os.is_dir_empty('dir that does not exist at all')
}
fn test_cp_all() {
// fileX -> dir/fileX
// Note: clean up of the files happens inside the cleanup_leftovers function
@ -792,7 +786,7 @@ fn test_truncate() ? {
mut f := os.create(filename) ?
f.write_string(hello) ?
f.close()
assert u64(hello.len) == os.file_size(filename)
assert hello.len == os.file_size(filename)
newlen := u64(40000)
os.truncate(filename, newlen) or { panic(err) }
assert newlen == os.file_size(filename)

View File

@ -14,8 +14,7 @@ import strings
* Inits
*
******************************************************************************/
// regex_base returns a regex object (`RE`) generated from `pattern` string and
// detailed information in re_err, err_pos, if an error occurred.
// regex create a regex object from the query string, retunr RE object and errors as re_err, err_pos
pub fn regex_base(pattern string) (RE, int, int) {
// init regex
mut re := RE{}

View File

@ -1,11 +1,13 @@
/*
* ATTENTION! Do not use this file as an example!
* For that, please look at `channel_select_2_test.v` or `channel_select_3_test.v`
*
* This test case uses the implementation in `sync/channels.v` directly
* in order to test it independently from the support in the core language
*/
module sync
// vtest retry: 6
// ATTENTION! Do not use this file as an example!
// For that, please look at `channel_select_2_test.v` or `channel_select_3_test.v`
// This test case uses the implementation in `sync/channels.v` directly
// in order to test it independently from the support in the core language
import time
fn do_rec_i64(mut ch Channel) {

View File

@ -18,7 +18,7 @@ fn test_count_10_times_1_cycle_should_result_10_cycles_with_sync() {
go count_one_cycle(mut counter, mut wg)
}
wg.wait()
assert counter.counter == u64(desired_iterations)
assert counter.counter == desired_iterations
eprintln(' with synchronization the counter is: ${counter.counter:10} , expectedly == ${desired_iterations:10}')
}

View File

@ -1821,9 +1821,6 @@ pub fn (stmt Stmt) check_c_expr() ? {
AssignStmt {
return
}
ForCStmt, ForInStmt, ForStmt {
return
}
ExprStmt {
if stmt.expr.is_expr() {
return

View File

@ -206,14 +206,6 @@ fn (mut v Builder) setup_ccompiler_options(ccompiler string) {
if v.pref.os == .macos && os.exists('/opt/procursus') {
ccoptions.linker_flags << '-Wl,-rpath,/opt/procursus/lib'
}
mut user_darwin_version := 999_999_999
mut user_darwin_ppc := false
$if macos {
user_darwin_version = os.uname().release.split('.')[0].int()
if os.uname().machine == 'Power Macintosh' {
user_darwin_ppc = true
}
}
ccoptions.debug_mode = v.pref.is_debug
ccoptions.guessed_compiler = v.pref.ccompiler
if ccoptions.guessed_compiler == 'cc' && v.pref.is_prod {
@ -260,10 +252,7 @@ fn (mut v Builder) setup_ccompiler_options(ccompiler string) {
}
if ccoptions.is_cc_gcc {
if ccoptions.debug_mode {
debug_options = ['-g']
if user_darwin_version > 9 {
debug_options << '-no-pie'
}
debug_options = ['-g', '-no-pie']
}
optimization_options = ['-O3', '-fno-strict-aliasing', '-flto']
}
@ -345,7 +334,7 @@ fn (mut v Builder) setup_ccompiler_options(ccompiler string) {
}
// macOS code can include objective C TODO remove once objective C is replaced with C
if v.pref.os == .macos || v.pref.os == .ios {
if !ccoptions.is_cc_tcc && !user_darwin_ppc {
if !ccoptions.is_cc_tcc {
ccoptions.source_args << '-x objective-c'
}
}

View File

@ -335,8 +335,7 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
left_elem_type := c.table.unaliased_type(left_info.elem_type)
right_info := right_sym.info as ast.Array
right_elem_type := c.table.unaliased_type(right_info.elem_type)
if left_type_unwrapped.nr_muls() == right_type_unwrapped.nr_muls()
&& left_info.nr_dims == right_info.nr_dims && left_elem_type == right_elem_type {
if left_info.nr_dims == right_info.nr_dims && left_elem_type == right_elem_type {
continue
}
}

View File

@ -204,9 +204,7 @@ pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type,
}
return
}
if got != ast.void_type {
return error('cannot use `$got_typ_str` as `$expected_typ_str`')
}
return error('cannot use `$got_typ_str` as `$expected_typ_str`')
}
// helper method to check if the type is of the same module.
@ -691,38 +689,3 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr
c.need_recheck_generic_fns = true
}
}
pub fn (c &Checker) sizeof_integer(a ast.Type) int {
t := if a in ast.unsigned_integer_type_idxs { a.flip_signedness() } else { a }
r := match t {
ast.char_type_idx, ast.i8_type_idx {
1
}
ast.i16_type_idx {
2
}
ast.int_type_idx {
4
}
ast.rune_type_idx {
4
}
ast.i64_type_idx {
8
}
ast.isize_type_idx {
if c.pref.m64 { 8 } else { 4 }
}
ast.int_literal_type {
s := c.table.type_to_str(a)
panic('`$s` has unknown size')
0
}
else {
s := c.table.type_to_str(a)
panic('`$s` is not an integer')
0
}
}
return r
}

View File

@ -640,18 +640,6 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
rt := c.table.sym(right_type).name
c.error('negative value cannot be compared with `$rt`', node.left.pos)
}
} else if is_left_type_signed != is_right_type_signed
&& left_type != ast.int_literal_type_idx
&& right_type != ast.int_literal_type_idx {
ls := c.sizeof_integer(left_type)
rs := c.sizeof_integer(right_type)
// prevent e.g. `u32 == i16` but not `u16 == i32` as max_u16 fits in i32
// TODO u32 == i32, change < to <=
if (is_left_type_signed && ls < rs) || (is_right_type_signed && rs < ls) {
lt := c.table.sym(left_type).name
rt := c.table.sym(right_type).name
c.error('`$lt` cannot be compared with `$rt`', node.pos)
}
}
}
}
@ -1675,9 +1663,7 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
c.inside_selector_expr = old_selector_expr
c.using_new_err_struct = using_new_err_struct_save
if typ == ast.void_type_idx {
// This means that the field has an undefined type.
// This error was handled before.
// c.error('`void` type has no fields', node.pos)
c.error('`void` type has no fields', node.pos)
return ast.void_type
}
node.expr_type = typ
@ -3697,8 +3683,8 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type {
for mut expr is ast.ParExpr {
expr = expr.expr
}
if expr in [ast.BoolLiteral, ast.CallExpr, ast.CharLiteral, ast.FloatLiteral, ast.IntegerLiteral,
ast.InfixExpr, ast.StringLiteral, ast.StringInterLiteral] {
if expr in [ast.BoolLiteral, ast.CallExpr, ast.CharLiteral, ast.FloatLiteral,
ast.IntegerLiteral, ast.InfixExpr, ast.StringLiteral, ast.StringInterLiteral] {
c.error('cannot take the address of $expr', node.pos)
}
if mut node.right is ast.IndexExpr {

View File

@ -578,17 +578,6 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
found = true
return ast.string_type
}
if !found && node.left is ast.CallExpr {
c.expr(node.left)
expr := node.left as ast.CallExpr
sym := c.table.sym(expr.return_type)
if sym.kind == .function {
info := sym.info as ast.FnType
node.return_type = info.func.return_type
found = true
func = info.func
}
}
// already prefixed (mod.fn) or C/builtin/main
if !found {
if f := c.table.find_fn(fn_name) {
@ -906,16 +895,6 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
if param.typ.has_flag(.generic) {
continue
}
if param_typ_sym.kind == .array && arg_typ_sym.kind == .array {
param_info := param_typ_sym.info as ast.Array
param_elem_type := c.table.unaliased_type(param_info.elem_type)
arg_info := arg_typ_sym.info as ast.Array
arg_elem_type := c.table.unaliased_type(arg_info.elem_type)
if param.typ.nr_muls() == arg_typ.nr_muls()
&& param_info.nr_dims == arg_info.nr_dims && param_elem_type == arg_elem_type {
continue
}
}
if c.pref.translated || c.file.is_translated {
// TODO duplicated logic in check_types() (check_types.v)
// Allow enums to be used as ints and vice versa in translated code
@ -1410,19 +1389,6 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
// if arg_typ_sym.kind == .string && typ_sym.has_method('str') {
// continue
// }
param_typ_sym := c.table.sym(exp_arg_typ)
arg_typ_sym := c.table.sym(got_arg_typ)
if param_typ_sym.kind == .array && arg_typ_sym.kind == .array {
param_info := param_typ_sym.info as ast.Array
param_elem_type := c.table.unaliased_type(param_info.elem_type)
arg_info := arg_typ_sym.info as ast.Array
arg_elem_type := c.table.unaliased_type(arg_info.elem_type)
if exp_arg_typ.nr_muls() == got_arg_typ.nr_muls()
&& param_info.nr_dims == arg_info.nr_dims
&& param_elem_type == arg_elem_type {
continue
}
}
if got_arg_typ != ast.void_type {
c.error('$err.msg() in argument ${i + 1} to `${left_sym.name}.$method_name`',
arg.pos)
@ -1777,9 +1743,6 @@ fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type ast.
mut ret_type := ast.void_type
match method_name {
'clone', 'move' {
if node.args.len != 0 {
c.error('`.${method_name}()` does not have any arguments', node.args[0].pos)
}
if method_name[0] == `m` {
c.fail_if_immutable(node.left)
}
@ -1791,9 +1754,6 @@ fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type ast.
ret_type = ret_type.clear_flag(.shared_f)
}
'keys' {
if node.args.len != 0 {
c.error('`.keys()` does not have any arguments', node.args[0].pos)
}
info := left_sym.info as ast.Map
typ := c.table.find_or_register_array(info.key_type)
ret_type = ast.Type(typ)
@ -1918,9 +1878,6 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
c.check_map_and_filter(false, elem_typ, node)
node.return_type = ast.bool_type
} else if method_name == 'clone' {
if node.args.len != 0 {
c.error('`.clone()` does not have any arguments', node.args[0].pos)
}
// need to return `array_xxx` instead of `array`
// in ['clone', 'str'] {
node.receiver_type = left_type.ref()
@ -1938,27 +1895,19 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
// c.warn('use `value in arr` instead of `arr.contains(value)`', node.pos)
if node.args.len != 1 {
c.error('`.contains()` expected 1 argument, but got $node.args.len', node.pos)
} else if !left_sym.has_method('contains') {
arg_typ := c.expr(node.args[0].expr)
c.check_expected_call_arg(arg_typ, elem_typ, node.language, node.args[0]) or {
c.error('$err.msg() in argument 1 to `.contains()`', node.args[0].pos)
} else {
arg_typ := ast.mktyp(c.expr(node.args[0].expr))
elem_typ_str := c.table.type_to_str(elem_typ)
arg_typ_str := c.table.type_to_str(arg_typ)
if !left_sym.has_method('contains') && elem_typ_str != arg_typ_str {
c.error('`.contains()` expected `$elem_typ_str` argument, but got `$arg_typ_str`',
node.pos)
}
}
node.return_type = ast.bool_type
} else if method_name == 'index' {
if node.args.len != 1 {
c.error('`.index()` expected 1 argument, but got $node.args.len', node.pos)
} else if !left_sym.has_method('index') {
arg_typ := c.expr(node.args[0].expr)
c.check_expected_call_arg(arg_typ, elem_typ, node.language, node.args[0]) or {
c.error('$err.msg() in argument 1 to `.index()`', node.args[0].pos)
}
}
node.return_type = ast.int_type
} else if method_name in ['first', 'last', 'pop'] {
if node.args.len != 0 {
c.error('`.${method_name}()` does not have any arguments', node.args[0].pos)
}
node.return_type = array_info.elem_type
if method_name == 'pop' {
c.fail_if_immutable(node.left)

View File

@ -95,9 +95,6 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
node.scope.update_var_type(node.key_var, key_type)
}
mut value_type := c.table.value_type(typ)
if sym.kind == .string {
value_type = ast.byte_type
}
if value_type == ast.void_type || typ.has_flag(.optional) {
if typ != ast.void_type {
c.error('for in: cannot index `${c.table.type_to_str(typ)}`', node.cond.pos())

View File

@ -296,7 +296,7 @@ fn (mut c Checker) smartcast_if_conds(node ast.Expr, mut scope ast.Scope) {
c.smartcast_if_conds(node.right, mut scope)
} else if node.op == .key_is {
right_expr := node.right
right_type := match right_expr {
mut right_type := match right_expr {
ast.TypeNode {
right_expr.typ
}
@ -308,10 +308,11 @@ fn (mut c Checker) smartcast_if_conds(node ast.Expr, mut scope ast.Scope) {
ast.Type(0)
}
}
right_type = c.unwrap_generic(right_type)
if right_type != ast.Type(0) {
left_sym := c.table.sym(node.left_type)
right_sym := c.table.sym(right_type)
mut expr_type := c.expr(node.left)
mut expr_type := c.unwrap_generic(c.expr(node.left))
if left_sym.kind == .aggregate {
expr_type = (left_sym.info as ast.Aggregate).sum_type
}
@ -321,7 +322,7 @@ fn (mut c Checker) smartcast_if_conds(node ast.Expr, mut scope ast.Scope) {
} else {
return
}
} else if !c.check_types(right_type, expr_type) && left_sym.kind != .sum_type {
} else if !c.check_types(right_type, expr_type) {
expect_str := c.table.type_to_str(right_type)
expr_str := c.table.type_to_str(expr_type)
c.error('cannot use type `$expect_str` as type `$expr_str`', node.pos)

View File

@ -162,10 +162,9 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym
c.expected_type = node.expected_type
low_expr := expr.low
high_expr := expr.high
final_cond_sym := c.table.final_sym(node.cond_type)
if low_expr is ast.IntegerLiteral {
if high_expr is ast.IntegerLiteral
&& (final_cond_sym.is_int() || final_cond_sym.info is ast.Enum) {
&& (cond_type_sym.is_int() || cond_type_sym.info is ast.Enum) {
low = low_expr.val.i64()
high = high_expr.val.i64()
if low > high {
@ -175,7 +174,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym
c.error('mismatched range types', low_expr.pos)
}
} else if low_expr is ast.CharLiteral {
if high_expr is ast.CharLiteral && final_cond_sym.kind in [.u8, .char, .rune] {
if high_expr is ast.CharLiteral && cond_type_sym.kind in [.u8, .char, .rune] {
low = low_expr.val[0]
high = high_expr.val[0]
if low > high {

View File

@ -34,7 +34,7 @@ pub fn (mut c Checker) return_stmt(mut node ast.Return) {
mut got_types := []ast.Type{}
mut expr_idxs := []int{}
for i, expr in node.exprs {
mut typ := c.expr(expr)
typ := c.expr(expr)
if typ == ast.void_type {
c.error('`$expr` used as value', node.pos)
}
@ -46,13 +46,6 @@ pub fn (mut c Checker) return_stmt(mut node ast.Return) {
expr_idxs << i
}
} else {
if expr is ast.Ident {
if expr.obj is ast.Var {
if expr.obj.smartcasts.len > 0 {
typ = c.unwrap_generic(expr.obj.smartcasts.last())
}
}
}
got_types << typ
expr_idxs << i
}

View File

@ -1,28 +0,0 @@
vlib/v/checker/tests/array_builtin_method_args_err.vv:4:18: error: `.clone()` does not have any arguments
2 | arr := [1, 2, 3]
3 |
4 | a1 := arr.clone(22)
| ~~
5 | println(a1)
6 |
vlib/v/checker/tests/array_builtin_method_args_err.vv:7:18: error: `.first()` does not have any arguments
5 | println(a1)
6 |
7 | a2 := arr.first('a2')
| ~~~~
8 | println(a2)
9 |
vlib/v/checker/tests/array_builtin_method_args_err.vv:10:17: error: `.last()` does not have any arguments
8 | println(a2)
9 |
10 | a3 := arr.last(1)
| ^
11 | println(a3)
12 |
vlib/v/checker/tests/array_builtin_method_args_err.vv:13:16: error: `.pop()` does not have any arguments
11 | println(a3)
12 |
13 | a4 := arr.pop(2)
| ^
14 | println(a4)
15 | }

View File

@ -1,15 +0,0 @@
fn main() {
arr := [1, 2, 3]
a1 := arr.clone(22)
println(a1)
a2 := arr.first('a2')
println(a2)
a3 := arr.last(1)
println(a3)
a4 := arr.pop(2)
println(a4)
}

View File

@ -1,8 +1,8 @@
vlib/v/checker/tests/array_contains_args_err.vv:3:26: error: cannot use `[]int` as `int` in argument 1 to `.contains()`
vlib/v/checker/tests/array_contains_args_err.vv:3:17: error: `.contains()` expected `int` argument, but got `[]int`
1 | fn main() {
2 | arr := [0]
3 | mut ret := [0].contains([0])
| ~~~
| ~~~~~~~~~~~~~
4 | ret = [0].contains()
5 | ret = [0, 1, 2].contains(0, 1, 2)
vlib/v/checker/tests/array_contains_args_err.vv:4:12: error: `.contains()` expected 1 argument, but got 0
@ -19,17 +19,17 @@ vlib/v/checker/tests/array_contains_args_err.vv:5:18: error: `.contains()` expec
| ~~~~~~~~~~~~~~~~~
6 | ret = [0].contains('a')
7 | ret = [0].contains(arr)
vlib/v/checker/tests/array_contains_args_err.vv:6:21: error: cannot use `string` as `int` in argument 1 to `.contains()`
vlib/v/checker/tests/array_contains_args_err.vv:6:12: error: `.contains()` expected `int` argument, but got `string`
4 | ret = [0].contains()
5 | ret = [0, 1, 2].contains(0, 1, 2)
6 | ret = [0].contains('a')
| ~~~
| ~~~~~~~~~~~~~
7 | ret = [0].contains(arr)
8 | println(ret)
vlib/v/checker/tests/array_contains_args_err.vv:7:21: error: cannot use `[]int` as `int` in argument 1 to `.contains()`
vlib/v/checker/tests/array_contains_args_err.vv:7:12: error: `.contains()` expected `int` argument, but got `[]int`
5 | ret = [0, 1, 2].contains(0, 1, 2)
6 | ret = [0].contains('a')
7 | ret = [0].contains(arr)
| ~~~
| ~~~~~~~~~~~~~
8 | println(ret)
9 | }

View File

@ -1,35 +0,0 @@
vlib/v/checker/tests/array_index_args_err.vv:3:23: error: cannot use `[]int` as `int` in argument 1 to `.index()`
1 | fn main() {
2 | arr := [0]
3 | mut ret := [0].index([0])
| ~~~
4 | ret = [0].index()
5 | ret = [0, 1, 2].index(0, 1, 2)
vlib/v/checker/tests/array_index_args_err.vv:4:12: error: `.index()` expected 1 argument, but got 0
2 | arr := [0]
3 | mut ret := [0].index([0])
4 | ret = [0].index()
| ~~~~~~~
5 | ret = [0, 1, 2].index(0, 1, 2)
6 | ret = [0].index('a')
vlib/v/checker/tests/array_index_args_err.vv:5:18: error: `.index()` expected 1 argument, but got 3
3 | mut ret := [0].index([0])
4 | ret = [0].index()
5 | ret = [0, 1, 2].index(0, 1, 2)
| ~~~~~~~~~~~~~~
6 | ret = [0].index('a')
7 | ret = [0].index(arr)
vlib/v/checker/tests/array_index_args_err.vv:6:18: error: cannot use `string` as `int` in argument 1 to `.index()`
4 | ret = [0].index()
5 | ret = [0, 1, 2].index(0, 1, 2)
6 | ret = [0].index('a')
| ~~~
7 | ret = [0].index(arr)
8 | println(ret)
vlib/v/checker/tests/array_index_args_err.vv:7:18: error: cannot use `[]int` as `int` in argument 1 to `.index()`
5 | ret = [0, 1, 2].index(0, 1, 2)
6 | ret = [0].index('a')
7 | ret = [0].index(arr)
| ~~~
8 | println(ret)
9 | }

View File

@ -1,9 +0,0 @@
fn main() {
arr := [0]
mut ret := [0].index([0])
ret = [0].index()
ret = [0, 1, 2].index(0, 1, 2)
ret = [0].index('a')
ret = [0].index(arr)
println(ret)
}

View File

@ -17,45 +17,10 @@ vlib/v/checker/tests/compare_unsigned_signed.vv:10:16: error: `u8` cannot be com
10 | _ = u8(-1) == -1 // false!
| ~~
11 | _ = -1 == u16(-1) // false!
12 |
12 | }
vlib/v/checker/tests/compare_unsigned_signed.vv:11:6: error: negative value cannot be compared with `u16`
9 | // unsigned == literal
10 | _ = u8(-1) == -1 // false!
11 | _ = -1 == u16(-1) // false!
| ~~
12 |
13 | // smaller unsigned == signed, OK
vlib/v/checker/tests/compare_unsigned_signed.vv:18:12: error: `i8` cannot be compared with `u16`
16 |
17 | // smaller signed == unsigned, NG
18 | _ = i8(0) == u16(0)
| ~~
19 | _ = i16(0) != u32(0)
20 | _ = int(0) == u64(0)
vlib/v/checker/tests/compare_unsigned_signed.vv:19:13: error: `i16` cannot be compared with `u32`
17 | // smaller signed == unsigned, NG
18 | _ = i8(0) == u16(0)
19 | _ = i16(0) != u32(0)
| ~~
20 | _ = int(0) == u64(0)
21 | _ = i32(0) == u64(0) // FIXME
vlib/v/checker/tests/compare_unsigned_signed.vv:20:13: error: `int` cannot be compared with `u64`
18 | _ = i8(0) == u16(0)
19 | _ = i16(0) != u32(0)
20 | _ = int(0) == u64(0)
| ~~
21 | _ = i32(0) == u64(0) // FIXME
22 | // swap order
vlib/v/checker/tests/compare_unsigned_signed.vv:23:13: error: `u16` cannot be compared with `i8`
21 | _ = i32(0) == u64(0) // FIXME
22 | // swap order
23 | _ = u16(0) == i8(0)
| ~~
24 | _ = u64(0) == i16(0)
25 | }
vlib/v/checker/tests/compare_unsigned_signed.vv:24:13: error: `u64` cannot be compared with `i16`
22 | // swap order
23 | _ = u16(0) == i8(0)
24 | _ = u64(0) == i16(0)
| ~~
25 | }
12 | }

View File

@ -9,17 +9,4 @@ fn main() {
// unsigned == literal
_ = u8(-1) == -1 // false!
_ = -1 == u16(-1) // false!
// smaller unsigned == signed, OK
_ = u16(-1) == int(-1)
_ = int(-1) != u8(-1)
// smaller signed == unsigned, NG
_ = i8(0) == u16(0)
_ = i16(0) != u32(0)
_ = int(0) == u64(0)
_ = i32(0) == u64(0) // FIXME
// swap order
_ = u16(0) == i8(0)
_ = u64(0) == i16(0)
}

View File

@ -1,3 +1,10 @@
vlib/v/checker/tests/if_match_expr.vv:8:6: error: `if` expression branch has unsupported statement (`v.ast.ForStmt`)
6 | if true {1} else {-1} // result
7 | } else {
8 | for {break}
| ^
9 | {}
10 | match true {true {} else {}} // statement not expression
vlib/v/checker/tests/if_match_expr.vv:9:2: error: `if` expression branch has unsupported statement (`v.ast.Block`)
7 | } else {
8 | for {break}

View File

@ -1,21 +0,0 @@
vlib/v/checker/tests/map_builtin_method_args_err.vv:4:16: error: `.clone()` does not have any arguments
2 | mut m := {11: 22}
3 |
4 | a1 := m.clone(11)
| ~~
5 | println(a1)
6 |
vlib/v/checker/tests/map_builtin_method_args_err.vv:7:15: error: `.move()` does not have any arguments
5 | println(a1)
6 |
7 | a2 := m.move(11)
| ~~
8 | println(a2)
9 |
vlib/v/checker/tests/map_builtin_method_args_err.vv:10:15: error: `.keys()` does not have any arguments
8 | println(a2)
9 |
10 | a3 := m.keys('aaa')
| ~~~~~
11 | println(a3)
12 | }

View File

@ -1,12 +0,0 @@
fn main() {
mut m := {11: 22}
a1 := m.clone(11)
println(a1)
a2 := m.move(11)
println(a2)
a3 := m.keys('aaa')
println(a3)
}

View File

@ -511,13 +511,8 @@ pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object {
return res
}
ast.AnonFn, ast.ArrayDecompose, ast.AsCast, ast.Assoc, ast.AtExpr, ast.CTempVar,
ast.ChanInit, ast.Comment, ast.ComptimeCall, ast.ComptimeSelector, ast.ComptimeType,
ast.ConcatExpr, ast.DumpExpr, ast.EmptyExpr, ast.EnumVal, ast.GoExpr, ast.IfGuardExpr,
ast.IndexExpr, ast.IsRefType, ast.Likely, ast.LockExpr, ast.MapInit, ast.MatchExpr,
ast.NodeError, ast.None, ast.OffsetOf, ast.OrExpr, ast.RangeExpr, ast.SelectExpr,
ast.SqlExpr, ast.TypeNode, ast.TypeOf, ast.UnsafeExpr {
e.error('unhandled expression ${typeof(expr).name}')
else {
e.error('unhandled expression $expr.type_name()')
}
}
return empty

View File

@ -1462,7 +1462,7 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
|| f.line_len + expr.pos().len > fmt.max_len[3]
}
}
mut line_break := f.array_init_break[f.array_init_depth - 1]
line_break := f.array_init_break[f.array_init_depth - 1]
mut penalty := if line_break { 0 } else { 4 }
if penalty > 0 {
if i == 0
@ -1480,26 +1480,14 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
}
single_line_expr := expr_is_single_line(expr)
if single_line_expr {
mut estr := ''
if !is_new_line && !f.buffering && f.line_len + expr.pos().len > fmt.max_len.last() {
if inc_indent {
estr = f.node_str(expr)
}
estr := f.node_str(expr)
if !is_new_line && !f.buffering && f.line_len + estr.len > fmt.max_len.last() {
f.writeln('')
is_new_line = true
if !inc_indent {
f.indent++
inc_indent = true
f.write_indent()
f.empty_line = false
estr = f.node_str(expr)
}
if i == 0 {
f.array_init_break[f.array_init_depth - 1] = true
line_break = true
}
} else {
estr = f.node_str(expr)
}
if !is_new_line && i > 0 {
f.write(' ')
@ -2327,11 +2315,7 @@ pub fn (mut f Fmt) par_expr(node ast.ParExpr) {
f.par_level++
f.write('(')
}
mut expr := node.expr
for mut expr is ast.ParExpr {
expr = expr.expr
}
f.expr(expr)
f.expr(node.expr)
if requires_paren {
f.par_level--
f.write(')')

View File

@ -6,7 +6,8 @@ const (
header: {
'Set-Cookie': ['special-7=","']
}
cookies: [&http.Cookie{
cookies: [
&http.Cookie{
name: 'special-7'
value: ','
raw: 'special-8=","'

View File

@ -12,13 +12,6 @@ fn wrapping_tests() {
'elit. Donec varius purus leo, vel maximus diam',
'finibus sed. Etiam eu urna ante. Nunc quis vehicula',
'velit. Sed at mauris et quam ornare tristique.']
multi_level := [
[1, 2, 3],
[
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec varius purus leo, vel maximus diam',
'finibus sed. Etiam eu urna ante. Nunc quis vehicula velit. Sed at mauris et quam ornare tristique.',
],
]
}
fn array_init_without_commas() {

View File

@ -9,10 +9,6 @@ fn main() {
fn wrapping_tests() {
my_arr := ['Lorem ipsum dolor sit amet, consectetur adipiscing', 'elit. Donec varius purus leo, vel maximus diam', 'finibus sed. Etiam eu urna ante. Nunc quis vehicula', 'velit. Sed at mauris et quam ornare tristique.']
multi_level := [
[1, 2, 3],
['Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec varius purus leo, vel maximus diam', 'finibus sed. Etiam eu urna ante. Nunc quis vehicula velit. Sed at mauris et quam ornare tristique.'],
]
}
fn array_init_without_commas() {

View File

@ -1,6 +0,0 @@
fn main() {
_, _ := (22 > 11), (43 > 22)
_ := (10 + 11)
_ := (11 * 2)
_ := (11 * 2)
}

View File

@ -1,6 +0,0 @@
fn main() {
_, _ := (((22 > 11))), (43 > 22)
_ := ((10 + 11))
_ := ((((((11 * 2))))))
_ := ((11 * 2))
}

View File

@ -78,7 +78,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
g.inside_lambda = false
return
}
need_tmp_var := g.inside_call && !g.inside_struct_init && node.exprs.len == 0
need_tmp_var := g.inside_call && !g.inside_struct_init
mut stmt_str := ''
mut tmp_var := ''
if need_tmp_var {

View File

@ -314,32 +314,11 @@ fn (mut g Gen) gen_assign_stmt(node_ ast.AssignStmt) {
}
func := right_sym.info as ast.FnType
ret_styp := g.typ(func.func.return_type)
mut call_conv := ''
mut msvc_call_conv := ''
for attr in func.func.attrs {
match attr.name {
'callconv' {
if g.is_cc_msvc {
msvc_call_conv = '__$attr.arg '
} else {
call_conv = '$attr.arg'
}
}
else {}
}
}
call_conv_attribute_suffix := if call_conv.len != 0 {
'__attribute__(($call_conv))'
} else {
''
}
g.write('$ret_styp ($msvc_call_conv*${g.get_ternary_name(ident.name)}) (')
g.write('$ret_styp (*${g.get_ternary_name(ident.name)}) (')
def_pos := g.definitions.len
g.fn_decl_params(func.func.params, voidptr(0), false)
g.definitions.go_back(g.definitions.len - def_pos)
g.write(')$call_conv_attribute_suffix')
g.write(')')
} else {
if is_decl {
if is_inside_ternary {

View File

@ -3286,7 +3286,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
if field_sym.kind == .sum_type {
g.write('*')
}
cast_sym := g.table.sym(g.unwrap_generic(typ))
cast_sym := g.table.sym(typ)
if i != 0 {
dot := if field.typ.is_ptr() { '->' } else { '.' }
sum_type_deref_field += ')$dot'
@ -5185,13 +5185,11 @@ fn (mut g Gen) enum_val(node ast.EnumVal) {
// g.write('${it.mod}${it.enum_name}_$it.val')
// g.enum_expr(node)
styp := g.typ(g.table.unaliased_type(node.typ))
// && g.inside_switch
if g.pref.translated && node.typ.is_number() {
if node.typ.is_number() {
// Mostly in translated code, when C enums are used as ints in switches
g.write('/*enum val is_number $node.mod styp=$styp*/_const_main__$node.val')
} else {
g.write('${styp}__$node.val')
// g.write('/*enum val is_number $node.mod styp=$styp*/')
}
g.write('${styp}__$node.val')
}
fn (mut g Gen) as_cast(node ast.AsCast) {

View File

@ -379,10 +379,7 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
defer {
g.tmp_count = ctmp
}
prev_inside_ternary := g.inside_ternary
g.inside_ternary = 0
g.stmts(node.stmts)
g.inside_ternary = prev_inside_ternary
if node.is_noreturn {
g.writeln('\twhile(1);')
}
@ -640,12 +637,11 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
// see my comment in parser near anon_fn
if node.left is ast.AnonFn {
g.expr(node.left)
} else if node.left is ast.IndexExpr && node.name == '' {
}
if node.left is ast.IndexExpr && node.name == '' {
g.is_fn_index_call = true
g.expr(node.left)
g.is_fn_index_call = false
} else if node.left is ast.CallExpr && node.name == '' {
g.expr(node.left)
}
if node.should_be_skipped {
return
@ -945,7 +941,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
g.gen_expr_to_string(node.left, rec_type)
return
} else if node.left.obj.smartcasts.len > 0 {
rec_type = g.unwrap_generic(node.left.obj.smartcasts.last())
rec_type = node.left.obj.smartcasts.last()
cast_sym := g.table.sym(rec_type)
if cast_sym.info is ast.Aggregate {
rec_type = cast_sym.info.types[g.aggregate_type_idx]
@ -1335,7 +1331,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
if expr.obj is ast.Var {
typ = expr.obj.typ
if expr.obj.smartcasts.len > 0 {
typ = g.unwrap_generic(expr.obj.smartcasts.last())
typ = expr.obj.smartcasts.last()
cast_sym := g.table.sym(typ)
if cast_sym.info is ast.Aggregate {
typ = cast_sym.info.types[g.aggregate_type_idx]
@ -2044,12 +2040,6 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as
g.expr(arg.expr)
g.write('->val')
return
} else if arg.expr is ast.ArrayInit {
if arg.expr.is_fixed {
if !arg.expr.has_it {
g.write('(${g.typ(arg.expr.typ)})')
}
}
}
g.expr_with_cast(arg.expr, arg_typ, expected_type)
if needs_closing {

View File

@ -299,15 +299,14 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) {
} else {
node.cond
}
field_accessor := if node.cond_type.is_ptr() { '->' } else { '.' }
i := if node.key_var in ['', '_'] { g.new_tmp_var() } else { node.key_var }
g.write('for (int $i = 0; $i < ')
g.expr(cond)
g.writeln('${field_accessor}len; ++$i) {')
g.writeln('.len; ++$i) {')
if node.val_var != '_' {
g.write('\tu8 ${c_name(node.val_var)} = ')
g.write('\tbyte ${c_name(node.val_var)} = ')
g.expr(cond)
g.writeln('${field_accessor}str[$i];')
g.writeln('.str[$i];')
}
} else if node.kind == .struct_ {
cond_type_sym := g.table.sym(node.cond_type)

View File

@ -20,9 +20,6 @@ fn (mut g Gen) need_tmp_var_in_if(node ast.IfExpr) bool {
if is_noreturn_callexpr(stmt.expr) {
return true
}
if stmt.expr is ast.MatchExpr {
return true
}
if stmt.expr is ast.CallExpr {
if stmt.expr.is_method {
left_sym := g.table.sym(stmt.expr.receiver_type)

View File

@ -708,8 +708,7 @@ fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) {
g.write(', _MOV(($elem_type_str[]){ ')
}
// if g.autofree
needs_clone := !g.is_builtin_mod && array_info.elem_type.idx() == ast.string_type_idx
&& array_info.elem_type.nr_muls() == 0
needs_clone := array_info.elem_type.idx() == ast.string_type_idx && !g.is_builtin_mod
if needs_clone {
g.write('string_clone(')
}

View File

@ -61,7 +61,8 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
}
g.inside_match_optional = true
}
if node.cond in [ast.Ident, ast.SelectorExpr, ast.IntegerLiteral, ast.StringLiteral, ast.FloatLiteral] {
if node.cond in [ast.Ident, ast.SelectorExpr, ast.IntegerLiteral, ast.StringLiteral,
ast.FloatLiteral] {
cond_var = g.expr_string(node.cond)
} else {
line := if is_expr {

View File

@ -156,7 +156,7 @@ fn (mut g Gen) str_val(node ast.StringInterLiteral, i int) {
if g.comptime_var_type_map.len > 0 || g.comptime_for_method.len > 0 {
exp_typ = expr.obj.typ
} else if expr.obj.smartcasts.len > 0 {
exp_typ = g.unwrap_generic(expr.obj.smartcasts.last())
exp_typ = expr.obj.smartcasts.last()
cast_sym := g.table.sym(exp_typ)
if cast_sym.info is ast.Aggregate {
exp_typ = cast_sym.info.types[g.aggregate_type_idx]

View File

@ -2426,8 +2426,8 @@ fn (mut g JsGen) match_expr(node ast.MatchExpr) {
g.inside_ternary = true
}
if node.cond in [ast.Ident, ast.SelectorExpr, ast.IntegerLiteral, ast.StringLiteral, ast.FloatLiteral,
ast.CallExpr, ast.EnumVal] {
if node.cond in [ast.Ident, ast.SelectorExpr, ast.IntegerLiteral, ast.StringLiteral,
ast.FloatLiteral, ast.CallExpr, ast.EnumVal] {
cond_var = CondExpr{node.cond}
} else {
s := g.new_tmp_var()

View File

@ -783,10 +783,9 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
} else {
p.tok.lit
}
is_generic_type := p.tok.kind == .name && p.tok.lit.len == 1 && p.tok.lit[0].is_capital()
types_only := p.tok.kind in [.amp, .ellipsis, .key_fn, .lsbr]
|| (p.peek_tok.kind == .comma && (p.table.known_type(argname) || is_generic_type))
|| (p.peek_tok.kind == .comma && p.table.known_type(argname))
|| p.peek_tok.kind == .dot || p.peek_tok.kind == .rpar
|| (p.tok.kind == .key_mut && (p.peek_token(2).kind == .comma
|| p.peek_token(2).kind == .rpar || (p.peek_tok.kind == .name

View File

@ -791,7 +791,7 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
spos := p.tok.pos()
name := p.check_name()
if name in p.label_names {
return p.error_with_pos('duplicate label `$name`', spos)
p.error_with_pos('duplicate label `$name`', spos)
}
p.label_names << name
p.next()
@ -812,7 +812,7 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
return stmt
}
else {
return p.error_with_pos('unknown kind of For statement', for_pos)
p.error_with_pos('unknown kind of For statement', for_pos)
}
}
}
@ -2327,18 +2327,6 @@ pub fn (mut p Parser) name_expr() ast.Expr {
p.error_with_pos('unexpected $p.prev_tok', p.prev_tok.pos())
}
node = p.call_expr(language, mod)
if p.tok.kind == .lpar && p.prev_tok.line_nr == p.tok.line_nr {
p.next()
pos := p.tok.pos()
args := p.call_args()
p.check(.rpar)
node = ast.CallExpr{
left: node
args: args
pos: pos
scope: p.scope
}
}
}
} else if (p.peek_tok.kind == .lcbr || (p.peek_tok.kind == .lt && lit0_is_capital))
&& (!p.inside_match || (p.inside_select && prev_tok_kind == .arrow && lit0_is_capital))

View File

@ -256,27 +256,30 @@ fn vweb_tmpl_${fn_name}() string {
match state {
.html {
line_t := line.trim_space()
if line_t.starts_with('span.') && line.ends_with('{') {
if line.starts_with('span.') && line.ends_with('{') {
// `span.header {` => `<span class='header'>`
class := line.find_between('span.', '{').trim_space()
source.writeln('<span class="$class">')
in_span = true
continue
} else if line_t.starts_with('.') && line.ends_with('{') {
}
if line.trim_space().starts_with('.') && line.ends_with('{') {
// `.header {` => `<div class='header'>`
class := line.find_between('.', '{').trim_space()
trimmed := line.trim_space()
source.write_string(strings.repeat(`\t`, line.len - trimmed.len)) // add the necessary indent to keep <div><div><div> code clean
source.writeln('<div class="$class">')
continue
} else if line_t.starts_with('#') && line.ends_with('{') {
}
if line.starts_with('#') && line.ends_with('{') {
// `#header {` => `<div id='header'>`
class := line.find_between('#', '{').trim_space()
source.writeln('<div id="$class">')
continue
} else if line_t == '}' {
source.write_string(strings.repeat(`\t`, line.len - line_t.len)) // add the necessary indent to keep <div><div><div> code clean
}
if line.trim_space() == '}' {
trimmed := line.trim_space()
source.write_string(strings.repeat(`\t`, line.len - trimmed.len)) // add the necessary indent to keep <div><div><div> code clean
if in_span {
source.writeln('</span>')
in_span = false

View File

@ -1,25 +0,0 @@
fn foofun(op rune) fn () string {
return match op {
`1` {
fn () string {
return '1 passed'
}
}
`2` {
fn () string {
return '2 passed'
}
}
else {
fn () string {
return 'Nor 1 or 2 passed'
}
}
}
}
fn test_anon_fn_decl_inside_ternary() {
a := foofun(`1`)
println(a())
assert a() == '1 passed'
}

View File

@ -1,19 +0,0 @@
fn foofun1(op string) fn () string {
return fn () string {
return 'x passed'
}
}
fn foofun2(op string) fn () int {
return fn () int {
return 22
}
}
fn test_fn_call_using_anon_fn_call_arg() {
println(main.foofun1('1')())
assert main.foofun1('1')() == 'x passed'
println(main.foofun2('1')())
assert main.foofun2('1')() == 22
}

View File

@ -1,24 +0,0 @@
fn show_array_of_u8(data []u8) string {
println(data)
return '$data'
}
struct Foo {}
fn (f Foo) show_array_of_u8(data []u8) string {
println(data)
return '$data'
}
fn test_fn_with_array_of_aliases_argument() {
a := [byte(1), 2, 3]
s1 := show_array_of_u8(a)
println(s1)
assert s1 == '[0x01, 0x02, 0x03]'
foo := Foo{}
s2 := foo.show_array_of_u8(a)
println(s2)
assert s2 == '[0x01, 0x02, 0x03]'
}

View File

@ -1,30 +0,0 @@
interface Any {}
struct ConcreteA {
a int
}
struct ConcreteB {
b int
}
struct Container {
concrete_a Any
concrete_b Any
}
fn cast_struct<T>(any_struct Any) &T {
if any_struct is T {
return any_struct
}
panic('cannot cast')
}
fn test_generic_empty_interface_to_multi_struct() {
concrete_a := cast_struct<ConcreteA>(ConcreteA{12345})
concrete_b := cast_struct<ConcreteB>(ConcreteB{54321})
println(concrete_a.a)
println(concrete_b.b)
assert concrete_a.a == 12345
assert concrete_b.b == 54321
}

View File

@ -1,13 +0,0 @@
fn test_generics_anon_fn_decl_with_type_only_arg() {
ret := func_b<int>(11, 22, add)
println(ret)
assert ret == 33
}
fn add(a int, b int) int {
return a + b
}
fn func_b<T>(x T, y T, f fn (T, T) T) T {
return f(x, y)
}

View File

@ -1,5 +1,3 @@
// vtest retry: 3
fn sum1(a int, b int) int {
sum_func1 := fn (a int, b int) int {
return a + b

View File

@ -1,12 +0,0 @@
fn test_if_expr_with_nested_match_expr() {
a := if true {
match `a` {
`a` { 0 }
else { 1 }
}
} else {
3
}
println(a)
assert a == 0
}

View File

@ -42,9 +42,9 @@ fn test_cmp_u32_and_signed() {
fn test_cmp_signed_and_u64() {
// ==
// assert int(1) == u64(1)
assert int(1) == u64(1)
// !=
// assert int(1) != u64(2)
assert int(1) != u64(2)
// >
assert !(int(1) > u64(1))
assert int(1) > u64(0)
@ -63,9 +63,9 @@ fn test_cmp_signed_and_u64() {
fn test_cmp_u64_and_signed() {
// ==
// assert u64(1) == int(1)
assert u64(1) == int(1)
// !=
// assert u64(2) != int(1)
assert u64(2) != int(1)
// >
assert !(u64(1) > int(1))
assert u64(1) > int(0)

View File

@ -1,11 +0,0 @@
97
98
99
abc
23
77
abc
> k: abc | v: xyz
> k: def | v: jkl
abc
abc

View File

@ -1,30 +0,0 @@
interface Any {}
fn abc(a Any) {
if a is string {
for x in a {
println(x)
}
}
if a is []u8 {
for x in a {
println(x)
}
}
if a is map[string]string {
for k, v in a {
println('> k: $k | v: $v')
}
}
println(@FN)
}
fn main() {
abc('abc')
abc([u8(23), 77])
abc({
'abc': 'xyz'
'def': 'jkl'
})
abc(123)
}

View File

@ -1 +0,0 @@
[[1, 2], [3, 3]]

View File

@ -1,4 +0,0 @@
fn main() {
a := [[1, 2]!, [3, 3]!]!
println([[a[0][0], a[0][1]]!, [a[1][0], a[1][1]]!]!)
}

View File

@ -1,9 +0,0 @@
fn test_match_aliases() {
a := byte(97)
ret := match a {
`0`...`9`, `a`...`f` { 'OK' }
else { 'NOT OK' }
}
println(ret)
assert ret == 'OK'
}

View File

@ -1,58 +0,0 @@
fn test_match_with_for_in_loop() {
a := 101
b := match a {
101 {
mut aa := []int{}
for i in 0 .. 3 {
aa << i
}
aa
}
else {
[0]
}
}
println(b)
assert b == [0, 1, 2]
}
fn test_match_with_for_c_loop() {
a := 101
b := match a {
101 {
mut aa := []int{}
for i := 0; i < 3; i++ {
aa << i
}
aa
}
else {
[0]
}
}
println(b)
assert b == [0, 1, 2]
}
fn test_match_with_for_loop() {
a := 101
b := match a {
101 {
mut aa := []int{}
mut i := 0
for {
aa << i
i++
if i == 3 {
break
}
}
aa
}
else {
[0]
}
}
println(b)
assert b == [0, 1, 2]
}

View File

@ -58,13 +58,13 @@ fn test_shift_operators() {
assert e == a
mut e3 := u64(1)
e3 <<= u32(i)
assert e3 == u64(b)
assert e3 == b
e3 >>= u32(i)
assert e == a
e3 <<= u64(i)
assert e3 == u64(b)
assert e3 == b
e3 >>= u64(i)
assert e3 == u64(a)
assert e3 == a
// Test shifts with custom int types
x := MyInt(2)
assert x << 2 == 8

View File

@ -1,18 +1,7 @@
fn test_creating_an_array_of_string_reference() {
fn test_str_array_of_reference() {
names := ['John', 'Paul', 'George', 'Ringo']
a := unsafe { [&names[0], &names[1]] }
println(a[0])
println(a)
assert '$a' == "[&'John', &'Paul']"
assert typeof(a[0]).name == '&string'
}
fn test_pushing_to_an_array_of_string_references() {
mut a := []&string{}
v1 := 'abc'
v2 := 'def'
a << &v1
a << &v2
assert *(a[0]) == 'abc'
assert *(a[1]) == 'def'
}