Include support in schemas

This commit is contained in:
Emery Hemingway 2021-08-31 13:02:27 +02:00
parent 5ca277b8c0
commit d671a2ac22
1 changed files with 15 additions and 7 deletions

View File

@ -5,6 +5,8 @@
## https://preserves.gitlab.io/preserves/preserves-schema.html
import std/[parseutils, macros, strutils, tables]
from os import absolutePath, isAbsolute, parentDir
import npeg
import ../preserves, ./parse, ./pegs
@ -65,6 +67,7 @@ type
definitions*: OrderedTable[string, SchemaNode]
ParseState = object
filepath: string
stack: Stack
schema: Schema
@ -210,16 +213,21 @@ const parser = peg("Schema", p: ParseState):
Clause <- (Version | EmbeddedTypeName | Include | Definition) * S * '.'
Version <- "version" * S * >(*Digit):
if not p.schema.version == 0: fail()
discard parseInt($1, p.schema.version)
if p.schema.version != 1: fail()
EmbeddedTypeName <- "embeddedType" * S * >("#f" | Ref):
if p.schema.embeddedType != "": fail()
if $1 != "#f": p.schema.embeddedType = $1
Include <- "include" * S * >(+Alnum):
# TODO: may be relative or absolute
match(readFile $1, p)
Include <- "include" * S * (>(+Alnum) | ('"' * >(@'"'))):
var ip = ParseState(
schema: p.schema,
filepath:
if isAbsolute($1): $1
else: absolutePath($1, p.filepath.parentDir))
ip.filePath.setLen(ip.filePath.high)
match(readFile ip.filepath, ip)
Definition <- >id * S * '=' * S * (OrPattern | AndPattern | Pattern):
if p.schema.definitions.hasKey $1:
@ -409,11 +417,11 @@ const parser = peg("Schema", p: ParseState):
proc match(text: string; p: var ParseState) =
let match = parser.match(text, p)
if not match.ok:
raise newException(ValueError, "failed to parse Preserves schema:\n" & text[0..<match.matchMax])
raise newException(ValueError, "failed to parse " & p.filepath & ":\n" & text[0..<match.matchMax])
proc parsePreservesSchema*(text: string): Schema =
proc parsePreservesSchema*(text, filepath: string): Schema =
## Parse a Preserves schema into an abstract syntax tree represented as a `Preserve`.
var p: ParseState
var p = ParseState(filepath: filepath)
new p.schema
match(text, p)
result = p.schema