vmft2: support for multiline comments, CompIf, AssertStmt, octal literals
parent
0e240458d3
commit
2a7bc63919
|
@ -1,5 +1,9 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
const (
|
||||||
|
rwxfile = os.join_path( os.temp_dir(), 'rwxfile.exe' )
|
||||||
|
)
|
||||||
|
|
||||||
fn testsuite_begin() {
|
fn testsuite_begin() {
|
||||||
cleanup_leftovers()
|
cleanup_leftovers()
|
||||||
}
|
}
|
||||||
|
@ -259,18 +263,18 @@ fn test_symlink() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_is_executable_writable_readable() {
|
fn test_is_executable_writable_readable() {
|
||||||
file_name := os.temp_dir() + os.path_separator + 'rwxfile.exe'
|
file_name := rwxfile
|
||||||
mut f := os.create(file_name) or {
|
mut f := os.create(file_name) or {
|
||||||
eprintln('failed to create file $file_name')
|
eprintln('failed to create file $file_name')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f.close()
|
f.close()
|
||||||
$if !windows {
|
$if !windows {
|
||||||
os.chmod(file_name, 0600) // mark as readable && writable, but NOT executable
|
os.chmod(file_name, 0o600) // mark as readable && writable, but NOT executable
|
||||||
assert os.is_writable(file_name)
|
assert os.is_writable(file_name)
|
||||||
assert os.is_readable(file_name)
|
assert os.is_readable(file_name)
|
||||||
assert !os.is_executable(file_name)
|
assert !os.is_executable(file_name)
|
||||||
os.chmod(file_name, 0700) // mark as executable too
|
os.chmod(file_name, 0o700) // mark as executable too
|
||||||
assert os.is_executable(file_name)
|
assert os.is_executable(file_name)
|
||||||
} $else {
|
} $else {
|
||||||
assert os.is_writable(file_name)
|
assert os.is_writable(file_name)
|
||||||
|
@ -332,4 +336,8 @@ fn cleanup_leftovers() {
|
||||||
os.rmdir_all('ex2')
|
os.rmdir_all('ex2')
|
||||||
os.rm('ex1.txt')
|
os.rm('ex1.txt')
|
||||||
os.rm('ex2.txt')
|
os.rm('ex2.txt')
|
||||||
|
if os.exists( rwxfile ) {
|
||||||
|
os.chmod(rwxfile, 0o777)
|
||||||
|
os.rm(rwxfile)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ pub struct StringInterLiteral {
|
||||||
pub:
|
pub:
|
||||||
vals []string
|
vals []string
|
||||||
exprs []Expr
|
exprs []Expr
|
||||||
|
expr_fmts []string
|
||||||
mut:
|
mut:
|
||||||
expr_types []table.Type
|
expr_types []table.Type
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,6 +214,11 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
|
||||||
ast.LineComment {
|
ast.LineComment {
|
||||||
f.writeln('// $it.text')
|
f.writeln('// $it.text')
|
||||||
}
|
}
|
||||||
|
ast.MultiLineComment {
|
||||||
|
f.writeln('/*')
|
||||||
|
f.writeln(it.text)
|
||||||
|
f.writeln('*/')
|
||||||
|
}
|
||||||
ast.Return {
|
ast.Return {
|
||||||
f.write('return')
|
f.write('return')
|
||||||
// multiple returns
|
// multiple returns
|
||||||
|
@ -246,6 +251,21 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
|
||||||
ast.TypeDecl {
|
ast.TypeDecl {
|
||||||
f.type_decl(it)
|
f.type_decl(it)
|
||||||
}
|
}
|
||||||
|
ast.AssertStmt {
|
||||||
|
f.write('assert ')
|
||||||
|
f.expr(it.expr)
|
||||||
|
f.writeln('')
|
||||||
|
}
|
||||||
|
ast.CompIf {
|
||||||
|
inversion := if it.is_not { '!' } else { '' }
|
||||||
|
f.writeln('\$if ${inversion}${it.val} {')
|
||||||
|
f.stmts(it.stmts)
|
||||||
|
if it.has_else {
|
||||||
|
f.writeln('} \$else {')
|
||||||
|
f.stmts(it.else_stmts)
|
||||||
|
}
|
||||||
|
f.writeln('}')
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
eprintln('fmt stmt: unknown node: ' + typeof(node))
|
eprintln('fmt stmt: unknown node: ' + typeof(node))
|
||||||
// exit(1)
|
// exit(1)
|
||||||
|
@ -535,6 +555,25 @@ fn (f mut Fmt) expr(node ast.Expr) {
|
||||||
f.write("'$it.val'")
|
f.write("'$it.val'")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ast.StringInterLiteral {
|
||||||
|
f.write("'")
|
||||||
|
for i, val in it.vals {
|
||||||
|
f.write(val)
|
||||||
|
if i>=it.exprs.len {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
f.write('$')
|
||||||
|
if it.expr_fmts[i].len > 0 {
|
||||||
|
f.write('{')
|
||||||
|
f.expr(it.exprs[i])
|
||||||
|
f.write(it.expr_fmts[i])
|
||||||
|
f.write('}')
|
||||||
|
}else{
|
||||||
|
f.expr(it.exprs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.write("'")
|
||||||
|
}
|
||||||
ast.StructInit {
|
ast.StructInit {
|
||||||
type_sym := f.table.get_type_symbol(it.typ)
|
type_sym := f.table.get_type_symbol(it.typ)
|
||||||
// `Foo{}` on one line if there are no fields
|
// `Foo{}` on one line if there are no fields
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
fn test_abc() {
|
||||||
|
assert 2 < 3
|
||||||
|
assert 2 == 2
|
||||||
|
assert 'abc' == 'abc'
|
||||||
|
assert 'abc'.len == 3
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
fn main() {
|
||||||
|
$if tinyc {
|
||||||
|
println('This will be compiled only when the compiler is tcc')
|
||||||
|
}
|
||||||
|
$if !windows {
|
||||||
|
println('This will get compiled on non-windows platforms.')
|
||||||
|
}
|
||||||
|
//
|
||||||
|
$if !linux {
|
||||||
|
println('Only non linux platforms will get this')
|
||||||
|
} $else {
|
||||||
|
println('This part is for linux only.')
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,8 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
x := 0xdeadbeef
|
x := 0xdeadbeef
|
||||||
u := 9978654321
|
u := 9978654321
|
||||||
|
o := 0o664
|
||||||
|
eprintln(' hex constant in decimal: $x')
|
||||||
|
eprintln(' u constant in decimal: $u')
|
||||||
|
eprintln('octal constant in decimal: $o')
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
/*
|
||||||
|
this is a very long comment
|
||||||
|
that is on multiple lines
|
||||||
|
and has some formatting in it
|
||||||
|
that should be
|
||||||
|
preserved.
|
||||||
|
*/
|
||||||
|
fn main() {
|
||||||
|
println('hello')
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println('Hello world, args: $os.args')
|
||||||
|
i := 123
|
||||||
|
a := 'abc'
|
||||||
|
b := 'xyz'
|
||||||
|
c := 'a: $a b: $b i: $i'
|
||||||
|
d := 'a: ${a:5s} b: ${b:-5s} i: ${i:20d}'
|
||||||
|
println('a: $a $b xxx')
|
||||||
|
eprintln('c: $c')
|
||||||
|
println(d)
|
||||||
|
}
|
|
@ -311,9 +311,10 @@ pub fn (p mut Parser) top_stmt() ast.Stmt {
|
||||||
return p.line_comment()
|
return p.line_comment()
|
||||||
}
|
}
|
||||||
.mline_comment {
|
.mline_comment {
|
||||||
// p.next()
|
comment := p.tok.lit
|
||||||
|
p.next()
|
||||||
return ast.MultiLineComment{
|
return ast.MultiLineComment{
|
||||||
text: p.scanner.line_comment
|
text: comment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1271,6 +1272,7 @@ fn (p mut Parser) string_expr() ast.Expr {
|
||||||
}
|
}
|
||||||
mut exprs := []ast.Expr
|
mut exprs := []ast.Expr
|
||||||
mut vals := []string
|
mut vals := []string
|
||||||
|
mut efmts := []string
|
||||||
// Handle $ interpolation
|
// Handle $ interpolation
|
||||||
for p.tok.kind == .string {
|
for p.tok.kind == .string {
|
||||||
vals << p.tok.lit
|
vals << p.tok.lit
|
||||||
|
@ -1280,24 +1282,31 @@ fn (p mut Parser) string_expr() ast.Expr {
|
||||||
}
|
}
|
||||||
p.check(.str_dollar)
|
p.check(.str_dollar)
|
||||||
exprs << p.expr(0)
|
exprs << p.expr(0)
|
||||||
|
mut efmt := []string
|
||||||
if p.tok.kind == .colon {
|
if p.tok.kind == .colon {
|
||||||
|
efmt << ':'
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
// ${num:-2d}
|
// ${num:-2d}
|
||||||
if p.tok.kind == .minus {
|
if p.tok.kind == .minus {
|
||||||
|
efmt << '-'
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
// ${num:2d}
|
// ${num:2d}
|
||||||
if p.tok.kind == .number {
|
if p.tok.kind == .number {
|
||||||
|
efmt << p.tok.lit
|
||||||
p.next()
|
p.next()
|
||||||
if p.tok.lit.len == 1 {
|
if p.tok.lit.len == 1 {
|
||||||
|
efmt << p.tok.lit
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
efmts << efmt.join('')
|
||||||
}
|
}
|
||||||
node = ast.StringInterLiteral{
|
node = ast.StringInterLiteral{
|
||||||
vals: vals
|
vals: vals
|
||||||
exprs: exprs
|
exprs: exprs
|
||||||
|
expr_fmts: efmts
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ fn filter_num_sep(txt byteptr, start int, end int) string {
|
||||||
mut i := start
|
mut i := start
|
||||||
mut i1 := 0
|
mut i1 := 0
|
||||||
for i < end {
|
for i < end {
|
||||||
if txt[i] != num_sep && txt[i] != `o` {
|
if txt[i] != num_sep {
|
||||||
b[i1] = txt[i]
|
b[i1] = txt[i]
|
||||||
i1++
|
i1++
|
||||||
}
|
}
|
||||||
|
@ -741,7 +741,7 @@ pub fn (s mut Scanner) scan() token.Token {
|
||||||
}
|
}
|
||||||
// Multiline comments
|
// Multiline comments
|
||||||
if nextc == `*` {
|
if nextc == `*` {
|
||||||
start := s.pos
|
start := s.pos + 2
|
||||||
mut nest_count := 1
|
mut nest_count := 1
|
||||||
// Skip comment
|
// Skip comment
|
||||||
for nest_count > 0 {
|
for nest_count > 0 {
|
||||||
|
@ -763,12 +763,9 @@ pub fn (s mut Scanner) scan() token.Token {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.pos++
|
s.pos++
|
||||||
end := s.pos + 1
|
if s.comments_mode == .parse_comments {
|
||||||
comment := s.text[start..end]
|
comment := s.text[start..(s.pos-1)].trim_space()
|
||||||
// if s.is_fmt {
|
return s.scan_res(.mline_comment, comment)
|
||||||
if false && s.comments_mode == .parse_comments {
|
|
||||||
s.line_comment = comment
|
|
||||||
return s.scan_res(.mline_comment, s.line_comment)
|
|
||||||
}
|
}
|
||||||
// Skip if not in fmt mode
|
// Skip if not in fmt mode
|
||||||
return s.scan()
|
return s.scan()
|
||||||
|
|
Loading…
Reference in New Issue