vmft2: support for multiline comments, CompIf, AssertStmt, octal literals
parent
0e240458d3
commit
2a7bc63919
|
@ -1,5 +1,9 @@
|
|||
import os
|
||||
|
||||
const (
|
||||
rwxfile = os.join_path( os.temp_dir(), 'rwxfile.exe' )
|
||||
)
|
||||
|
||||
fn testsuite_begin() {
|
||||
cleanup_leftovers()
|
||||
}
|
||||
|
@ -259,18 +263,18 @@ fn test_symlink() {
|
|||
}
|
||||
|
||||
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 {
|
||||
eprintln('failed to create file $file_name')
|
||||
return
|
||||
}
|
||||
f.close()
|
||||
$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_readable(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)
|
||||
} $else {
|
||||
assert os.is_writable(file_name)
|
||||
|
@ -332,4 +336,8 @@ fn cleanup_leftovers() {
|
|||
os.rmdir_all('ex2')
|
||||
os.rm('ex1.txt')
|
||||
os.rm('ex2.txt')
|
||||
if os.exists( rwxfile ) {
|
||||
os.chmod(rwxfile, 0o777)
|
||||
os.rm(rwxfile)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ pub struct StringInterLiteral {
|
|||
pub:
|
||||
vals []string
|
||||
exprs []Expr
|
||||
expr_fmts []string
|
||||
mut:
|
||||
expr_types []table.Type
|
||||
}
|
||||
|
|
|
@ -214,6 +214,11 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
|
|||
ast.LineComment {
|
||||
f.writeln('// $it.text')
|
||||
}
|
||||
ast.MultiLineComment {
|
||||
f.writeln('/*')
|
||||
f.writeln(it.text)
|
||||
f.writeln('*/')
|
||||
}
|
||||
ast.Return {
|
||||
f.write('return')
|
||||
// multiple returns
|
||||
|
@ -246,6 +251,21 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
|
|||
ast.TypeDecl {
|
||||
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 {
|
||||
eprintln('fmt stmt: unknown node: ' + typeof(node))
|
||||
// exit(1)
|
||||
|
@ -535,6 +555,25 @@ fn (f mut Fmt) expr(node ast.Expr) {
|
|||
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 {
|
||||
type_sym := f.table.get_type_symbol(it.typ)
|
||||
// `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() {
|
||||
x := 0xdeadbeef
|
||||
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()
|
||||
}
|
||||
.mline_comment {
|
||||
// p.next()
|
||||
comment := p.tok.lit
|
||||
p.next()
|
||||
return ast.MultiLineComment{
|
||||
text: p.scanner.line_comment
|
||||
text: comment
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1271,6 +1272,7 @@ fn (p mut Parser) string_expr() ast.Expr {
|
|||
}
|
||||
mut exprs := []ast.Expr
|
||||
mut vals := []string
|
||||
mut efmts := []string
|
||||
// Handle $ interpolation
|
||||
for p.tok.kind == .string {
|
||||
vals << p.tok.lit
|
||||
|
@ -1280,24 +1282,31 @@ fn (p mut Parser) string_expr() ast.Expr {
|
|||
}
|
||||
p.check(.str_dollar)
|
||||
exprs << p.expr(0)
|
||||
mut efmt := []string
|
||||
if p.tok.kind == .colon {
|
||||
efmt << ':'
|
||||
p.next()
|
||||
}
|
||||
// ${num:-2d}
|
||||
if p.tok.kind == .minus {
|
||||
efmt << '-'
|
||||
p.next()
|
||||
}
|
||||
// ${num:2d}
|
||||
if p.tok.kind == .number {
|
||||
efmt << p.tok.lit
|
||||
p.next()
|
||||
if p.tok.lit.len == 1 {
|
||||
efmt << p.tok.lit
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
efmts << efmt.join('')
|
||||
}
|
||||
node = ast.StringInterLiteral{
|
||||
vals: vals
|
||||
exprs: exprs
|
||||
expr_fmts: efmts
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ fn filter_num_sep(txt byteptr, start int, end int) string {
|
|||
mut i := start
|
||||
mut i1 := 0
|
||||
for i < end {
|
||||
if txt[i] != num_sep && txt[i] != `o` {
|
||||
if txt[i] != num_sep {
|
||||
b[i1] = txt[i]
|
||||
i1++
|
||||
}
|
||||
|
@ -741,7 +741,7 @@ pub fn (s mut Scanner) scan() token.Token {
|
|||
}
|
||||
// Multiline comments
|
||||
if nextc == `*` {
|
||||
start := s.pos
|
||||
start := s.pos + 2
|
||||
mut nest_count := 1
|
||||
// Skip comment
|
||||
for nest_count > 0 {
|
||||
|
@ -763,12 +763,9 @@ pub fn (s mut Scanner) scan() token.Token {
|
|||
}
|
||||
}
|
||||
s.pos++
|
||||
end := s.pos + 1
|
||||
comment := s.text[start..end]
|
||||
// if s.is_fmt {
|
||||
if false && s.comments_mode == .parse_comments {
|
||||
s.line_comment = comment
|
||||
return s.scan_res(.mline_comment, s.line_comment)
|
||||
if s.comments_mode == .parse_comments {
|
||||
comment := s.text[start..(s.pos-1)].trim_space()
|
||||
return s.scan_res(.mline_comment, comment)
|
||||
}
|
||||
// Skip if not in fmt mode
|
||||
return s.scan()
|
||||
|
|
Loading…
Reference in New Issue