vmft2: support for multiline comments, CompIf, AssertStmt, octal literals

pull/4113/head
Delyan Angelov 2020-03-24 23:18:58 +02:00 committed by GitHub
parent 0e240458d3
commit 2a7bc63919
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 114 additions and 13 deletions

View File

@ -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)
}
}

View File

@ -66,6 +66,7 @@ pub struct StringInterLiteral {
pub:
vals []string
exprs []Expr
expr_fmts []string
mut:
expr_types []table.Type
}

View File

@ -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

View File

@ -0,0 +1,6 @@
fn test_abc() {
assert 2 < 3
assert 2 == 2
assert 'abc' == 'abc'
assert 'abc'.len == 3
}

View File

@ -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.')
}
}

View File

@ -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')
}

View File

@ -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')
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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()