vweb: $html

pull/5250/head
Alexander Medvednikov 2020-06-06 21:36:24 +02:00
parent 16bf300934
commit 4d5ac1e16d
7 changed files with 88 additions and 9 deletions

View File

@ -27,15 +27,15 @@ pub fn (mut app App) json_endpoint() {
pub fn (mut app App) index() { pub fn (mut app App) index() {
app.cnt++ app.cnt++
app.vweb.text('Hello world from vweb') //app.vweb.text('Hello world from vweb')
//$vweb.html() $vweb.html()
} }
pub fn (mut app App) reset() { pub fn (mut app App) reset() {
} }
pub fn (mut app App) text() { pub fn (mut app App) text() {
app.vweb.text('Hello world') app.vweb.text('Hello world from vweb')
} }
pub fn (mut app App) cookie() { pub fn (mut app App) cookie() {

View File

@ -781,6 +781,8 @@ pub struct ComptimeCall {
pub: pub:
method_name string method_name string
left Expr left Expr
is_vweb bool
vweb_stmts []Stmt
pub mut: pub mut:
sym table.TypeSymbol sym table.TypeSymbol
} }

View File

@ -4350,6 +4350,10 @@ fn (mut g Gen) interface_call(typ, interface_type table.Type) {
} }
fn (g &Gen) comptime_call(node ast.ComptimeCall) { fn (g &Gen) comptime_call(node ast.ComptimeCall) {
if node.is_vweb {
g.writeln('vweb__Context_html(&app-> vweb, tmpl_res)')
return
}
g.writeln('// $' + 'method call. sym="$node.sym.name"') g.writeln('// $' + 'method call. sym="$node.sym.name"')
mut j := 0 mut j := 0
for method in node.sym.methods { for method in node.sym.methods {

View File

@ -8,6 +8,8 @@ import v.ast
import v.pref import v.pref
import v.vmod import v.vmod
import v.table import v.table
import vweb.tmpl
import v.token
const ( const (
supported_platforms = ['windows', 'mac', 'macos', 'darwin', 'linux', 'freebsd', 'openbsd', supported_platforms = ['windows', 'mac', 'macos', 'darwin', 'linux', 'freebsd', 'openbsd',
@ -76,14 +78,81 @@ fn (mut p Parser) hash() ast.HashStmt {
} }
} }
struct ParserState {
scanner_pos int
tok token.Token
prev_tok token.Token
peek_tok token.Token
peek_tok2 token.Token
peek_tok3 token.Token
}
pub fn (p &Parser) save_state() ParserState {
return ParserState{
scanner_pos: p.scanner.pos
tok: p.tok
prev_tok: p.prev_tok
peek_tok: p.peek_tok
peek_tok2: p.peek_tok2
peek_tok3: p.peek_tok3
}
}
pub fn (mut p Parser) restore_state(state ParserState) {
p.scanner.pos = state.scanner_pos
p.tok = state.tok
p.prev_tok = state.prev_tok
p.peek_tok = state.peek_tok
p.peek_tok2 = state.peek_tok2
p.peek_tok3 = state.peek_tok3
}
fn (mut p Parser) vweb() ast.ComptimeCall { fn (mut p Parser) vweb() ast.ComptimeCall {
p.check(.dollar) p.check(.dollar)
p.check(.name) // skip `vweb.html()` TODO p.check(.name) // skip `vweb.html()` TODO
p.check(.dot) p.check(.dot)
pos := p.scanner.pos
p.check(.name) p.check(.name)
p.check(.lpar) p.check(.lpar)
p.check(.rpar) p.check(.rpar)
return ast.ComptimeCall{} state := p.save_state()
// Compile vweb html template to V code, parse that V code and embed the resulting V function
// that returns an html string.
mut path := p.cur_fn_name + '.html'
// if p.pref.is_debug {
println('>>> compiling vweb HTML template "$path"')
v_code := tmpl.compile_file(path)
if p.pref.verbose {
println('\n\n')
println('>>> vweb template for ${path}:')
println(v_code)
println('>>> end of vweb template END')
println('\n\n')
p.scanner.text = p.scanner.text[..pos] + v_code + p.scanner.text[pos..]
println(p.scanner.text)
}
// }
/*
if !os.exists(path) {
// Can't find the template file in current directory,
// try looking next to the vweb program, in case it's run with
// v path/to/vweb_app.v
path = os.dir(p.scanner.file_path) + '/' + path
if !os.exists(path) {
p.error('vweb HTML template "$path" not found')
}
}
*/
p.restore_state(state)
p.scanner.pos = pos + v_code.len + 1
/*
println('restored:')
println(p.scanner.text[p.scanner.pos..])
println('=============')
*/
return ast.ComptimeCall{
is_vweb: true
}
} }
fn (mut p Parser) comp_if() ast.Stmt { fn (mut p Parser) comp_if() ast.Stmt {

View File

@ -265,6 +265,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
}) })
} }
// Body // Body
p.cur_fn_name = name
mut stmts := []ast.Stmt{} mut stmts := []ast.Stmt{}
no_body := p.tok.kind != .lcbr no_body := p.tok.kind != .lcbr
body_start_pos := p.peek_tok.position() body_start_pos := p.peek_tok.position()

View File

@ -54,6 +54,7 @@ mut:
expecting_type bool // `is Type`, expecting type expecting_type bool // `is Type`, expecting type
errors []errors.Error errors []errors.Error
warnings []errors.Warning warnings []errors.Warning
cur_fn_name string
} }
// for tests // for tests

View File

@ -34,10 +34,11 @@ pub fn compile_template(content string) string {
mut s := strings.new_builder(1000) mut s := strings.new_builder(1000)
// base := path.all_after_last('/').replace('.html', '') // base := path.all_after_last('/').replace('.html', '')
s.writeln(" s.writeln("
mut sb := strings.new_builder(${lines.len * 30}) // === vweb html template ===
header := \' \' // TODO remove mut sb := strings.new_builder(${lines.len * 30})
_ = header header := \' \' // TODO remove
//footer := \'footer\' _ = header
//footer := \'footer\'
") ")
s.writeln(str_start) s.writeln(str_start)
mut in_css := true // false mut in_css := true // false
@ -88,6 +89,7 @@ _ = header
} }
} }
s.writeln(str_end) s.writeln(str_end)
s.writeln('tmpl_res := sb.str() }') s.writeln('tmpl_res := sb.str() ')
s.writeln('// === end of vweb html template ===')
return s.str() return s.str()
} }