diff --git a/compiler/cbuilderdecls.nim b/compiler/cbuilderdecls.nim index 70d7cc364f..081a197d79 100644 --- a/compiler/cbuilderdecls.nim +++ b/compiler/cbuilderdecls.nim @@ -471,9 +471,31 @@ template addProcParams(builder: var Builder, params: out ProcParamBuilder, body: body finishProcParamBuilder(builder, params) +template addProcHeaderWithParams(builder: var Builder, callConv: TCallingConvention, + name: string, rettype: Snippet, paramBuilder: typed) = + # on nifc should build something like (proc name params type pragmas + # with no body given + # or enforce this with secondary builder object + builder.add(CallingConvToStr[callConv]) + builder.add("(") + builder.add(rettype) + builder.add(", ") + builder.add(name) + builder.add(")") + paramBuilder + +proc addProcHeader(builder: var Builder, callConv: TCallingConvention, + name: string, rettype, params: Snippet) = + # on nifc should build something like (proc name params type pragmas + # with no body given + # or enforce this with secondary builder object + addProcHeaderWithParams(builder, callConv, name, rettype): + builder.add(params) + proc addProcHeader(builder: var Builder, m: BModule, prc: PSym, name: string, params, rettype: Snippet, addAttributes: bool) = # on nifc should build something like (proc name params type pragmas # with no body given + # or enforce this with secondary builder object let noreturn = isNoReturn(m, prc) if sfPure in prc.flags and hasDeclspec in extccomp.CC[m.config.cCompiler].props: builder.add("__declspec(naked) ") @@ -525,3 +547,18 @@ proc addProcVar(builder: var Builder, m: BModule, prc: PSym, name: string, param builder.add(" __attribute__((noreturn))") # ensure we are just adding a variable: builder.add(";\n") + +proc addProcVar(builder: var Builder, callConv: TCallingConvention, + name: string, params, rettype: Snippet, isStatic = false) = + # on nifc, builds full variable + if isStatic: + builder.add("static ") + builder.add(CallingConvToStr[callConv]) + builder.add("_PTR(") + builder.add(rettype) + builder.add(", ") + builder.add(name) + builder.add(")") + builder.add(params) + # ensure we are just adding a variable: + builder.add(";\n") diff --git a/compiler/cbuilderexprs.nim b/compiler/cbuilderexprs.nim index 856b1c5c5b..58ac496002 100644 --- a/compiler/cbuilderexprs.nim +++ b/compiler/cbuilderexprs.nim @@ -29,6 +29,9 @@ proc procPtrTypeUnnamed(rettype, params: Snippet): Snippet = proc procPtrTypeUnnamedNimCall(rettype, params: Snippet): Snippet = rettype & "(N_RAW_NIMCALL*)" & params +proc procPtrTypeUnnamed(callConv: TCallingConvention, rettype, params: Snippet): Snippet = + CallingConvToStr[callConv] & "_PTR(" & rettype & ", )" & params + proc cCast(typ, value: Snippet): Snippet = "((" & typ & ") " & value & ")" diff --git a/compiler/cbuilderstmts.nim b/compiler/cbuilderstmts.nim index e2d272e795..aaba9eb7ca 100644 --- a/compiler/cbuilderstmts.nim +++ b/compiler/cbuilderstmts.nim @@ -119,6 +119,61 @@ template addForRangeInclusive(builder: var Builder, i, start, bound: Snippet, bo body builder.add("}\n") +template addSwitchStmt(builder: var Builder, val: Snippet, body: typed) = + builder.add("switch (") + builder.add(val) + builder.add(") {\n") + body + builder.add("}\n") + +template addSingleSwitchCase(builder: var Builder, val: Snippet, body: typed) = + builder.add("case ") + builder.add(val) + builder.add(":\n") + body + +type + SwitchCaseState = enum + None, Of, Else, Finished + SwitchCaseBuilder = object + state: SwitchCaseState + +proc addCase(builder: var Builder, info: var SwitchCaseBuilder, val: Snippet) = + if info.state != Of: + assert info.state == None + info.state = Of + builder.add("case ") + builder.add(val) + builder.add(":\n") + +proc addCaseRange(builder: var Builder, info: var SwitchCaseBuilder, first, last: Snippet) = + if info.state != Of: + assert info.state == None + info.state = Of + builder.add("case ") + builder.add(first) + builder.add(" ... ") + builder.add(last) + builder.add(":\n") + +proc addCaseElse(builder: var Builder, info: var SwitchCaseBuilder) = + assert info.state == None + info.state = Else + builder.add("default:\n") + +template addSwitchCase(builder: var Builder, info: out SwitchCaseBuilder, caseBody, body: typed) = + info = SwitchCaseBuilder(state: None) + caseBody + info.state = Finished + body + +template addSwitchElse(builder: var Builder, body: typed) = + builder.add("default:\n") + body + +proc addBreak(builder: var Builder) = + builder.add("break;\n") + template addScope(builder: var Builder, body: typed) = builder.add("{") body diff --git a/compiler/ccgreset.nim b/compiler/ccgreset.nim index 6caeb80849..b6f5c1e10a 100644 --- a/compiler/ccgreset.nim +++ b/compiler/ccgreset.nim @@ -27,25 +27,28 @@ proc specializeResetN(p: BProc, accessor: Rope, n: PNode; if disc.loc.snippet == "": fillObjectFields(p.module, typ) if disc.loc.t == nil: internalError(p.config, n.info, "specializeResetN()") - lineF(p, cpsStmts, "switch ($1.$2) {$n", [accessor, disc.loc.snippet]) - for i in 1..