OCaml type constructors in C = <unknown constructor> - c

I've written some OCaml bindings for some C code; they seem to work fine, except that, at the interpreter, the type constructor appears to be opaque to OCaml. So, for example:
# #load "foo.cma" ;;
# open Foo ;;
# let b = barbie "bar";;
val b : Foo.kung = <unknown constructor>
# let k = ken "kenny" ;;
val k : Foo.tza = <abstr>
I'm trying to get rid of the <unknown constructor> and replace it with a meaningful print.
The contents of foo.ml are:
type kung = Tsau of string [##boxed] ;;
type tza ;; (* Obviously, an abstract type *)
external barbie : string -> kung = "barbie_doll" ;;
external ken : string -> tza = "ken_doll" ;;
The C code is the minimal amount of code to get this to work:
CAMLprim value barbie(value vstr) { ... }
CAMLprim value ken(value vsttr) { ... }
The actual C code uses caml_alloc_custom() to hold stuff; and obviously has to return what caml_alloc_custom() alloced, so that it doesn't get lost. That's the core reason for using custom types: so I can return the custom malloc's.
Even though these types are abstract or opaque, I'd like to have the let expression print something meaningful. For example, perhaps this?
val b : Foo.kung = "Hi my name is bar"
val k : Foo.tza = "Yo duude it's kenny"
The second question would be: if it's possible to print something meaningful, what should it be? Obviously, the constructors were invoked with strings, so whatever is printed should include those string values...
The third question is: is it possible to specify types and type constructors in C? I suspect that the answer is "obviously no", because OCaml types are static, compile-time types, and are not dynamically constructable. But it never hurts to ask. I mean, the ocaml interpreter is able to deal with brand new type declarations just fine, so somehow, OCaml types aren't entirely static; there's some kind of 'dynamic' aspect to them. I've not found any documentation on this.

As suggested in a comment, the answer is to use #install_printer, which is briefly touched on in the toplevel documentation. This is but a hint: example code as follows (keeping with the earlier example).
In foostubs.ml:
(** Signature declarations for C functions *)
external kung_prt : kung -> string = "c_kung_str" ;;
(* Need to #install_printer kung_pretty ;;
* FYI, the OCaml documentation is confusing
* as to what a Format.formatter actually is:
* it is used like a C stream or outport. *)
let kung_pretty : Format.formatter -> kung -> unit =
function oport ->
fun x -> Format.fprintf oport "Hi %s" (kung_prt x) ;;
The printer in C would look like this:
CAMLprim value c_kung_str(value vkung)
{
CAMLparam1(vkung);
const char* name = String_val(vkung);
char buff[200];
strcpy(buff, "my name is ");
strncat(buff, name, 200);
CAMLreturn(caml_copy_string(buff));
}
Then, either you have to tell the user to #install_printer kung_pretty ;; or, better yet, provide the user with a setupfoo.ml that does this, and tell them to #use "setupfoo.ml".

Related

What is ArrayBuffer copyToArray's Implementation?

When I navigate ArrayBuffer[Byte]().toArray implementation in my IDE, it takes me to,
def toArray[B >: A : ClassTag]: Array[B] = {
if (isTraversableAgain) {
val result = new Array[B](size)
copyToArray(result, 0)
result
}
else toBuffer.toArray
}
copyToArray implementation takes me to,
def copyToArray[B >: A](xs: Array[B], start: Int): Unit =
copyToArray(xs, start, xs.length - start)
the copyToArray with three args terminates in,
def copyToArray[B >: A](xs: Array[B], start: Int, len: Int): Unit
Cannot locate what implementation of copyToArray is used on runtime. What's the implementation that's used? Is there a way to discover the implementations IDE doesn't trivially navigate to?
The toArray and copyToArray[B >: A](Array[B], Int) definitions are in some superclass/supertrait of ArrayBuffer. Because you are already looking at a supertype, when you ask your IDE to take you to the definition of copyToArray[B >: A](Array[B], Int, Int), it only looks further "up" the inheritance tree, and apparently it only finds an abstract declaration for it. You need to look "down" to find the actual implementation overrides this declaration. Your IDE should have some kind of "find implementations" function. In this case, the ArrayBuffer class itself has the final definition.

'withUnsafeBytes' is deprecated warning when passing void* argument to c function in swift 5

I have a library parsing FIT file in swift using an externally provided c library. The parsing function takes as argument a void * data.
To call the function, I was converting the data using data.withUnsafeBytes( { (ptr: UnsafePointer<UInt8>) in ...} to build the argument to the c function and it was working fine.
After the upgrade of Xcode to swift 5, I now get a deprecated warning
'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R instead
I couldn't work out how to fix the code to remove the deprecated warning. The code has been working fine and without warning in swift 4
I tried to change the argument in the closure to take UnsafeRawBufferPointer instead of the UnsafePointer but this resulted in an error in calling the function: Cannot convert 'UnsafeRawBufferPointer' to expected argument type 'UnsafeRawPointer?'
This is a small swift file to show the problem:
import Foundation
// Create sample data (Typically would be read from a file
let data = Data(repeating: 1, count: 10)
data.withUnsafeBytes( { (ptr : UnsafePointer<UInt8>) in
// call the c function with the void* argument
let value = readFITfile(ptr)
print( value )
})
And an example c function
unsigned readFITfile(const void * data){
//Silly example to show it works, just returning the value of pointer as int
//Typically would parse the data and return a structure
return (unsigned)data;
}
I saved a small repo with the above code here https://github.com/roznet/swift2c and the full scale project with the parsing of the file is here https://github.com/roznet/fit-sdk-swift
You have to change the closure argument to UnsafeRawBufferPointer and then take its baseAdress (which is a UnsafeRawPointer?, the Swift equivalent of void * in C):
data.withUnsafeBytes( { (ptr : UnsafeRawBufferPointer) in
let value = readFITfile(ptr.baseAddress)
// ...
})
The Swift compiler can also infer the closure argument type automatically:
data.withUnsafeBytes( { ptr in
let value = readFITfile(ptr.baseAddress)
// ...
})
For more information about this problem, see withUnsafeBytes Data API confusion in the Swift forum.
To get UnsafePointer now you should do something like that
data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) in
if let ptrAddress = ptr.baseAddress, ptr.count > 0 {
let pointer = ptrAddress.assumingMemoryBound(to: UInt8.self) // here you got UnsafePointer<UInt8>
let value = readFITfile(ptr)
print( value )
} else {
// Here you should provide some error handling if you want ofc
}
}

Can you store functions in an array and call them as needed?

I am new to programming (1 week), so this maybe a silly question, but here goes...
Using Swift (on the XCode program) I have defined some functions (Func1, Func2 etc) which take an array of integers, and swaps certain values within the array.
I have tried creating a new, separate array which contains Func1, Func2 etc , and then I would like to, based on a randomly generated number, (e.g. 10204), apply the functions as needed.
So, for example, the number 10204 would apply Func1, Func0, Func2, Func0, Func4 to the array.
I have tried looking at other questions on this site for ideas, but nothing seems to do the job, despite numerous attempts. Here is what I am trying to do - these two functions manipulate integers in an array called "cubePos"
func UC(){
(cubePos[0] , cubePos[17])
=
(cubePos[17] , cubePos[19])
}
func DC(){
(cubePos[26] , cubePos[41])
=
(cubePos[41] , cubePos[43])
}
Both of these functions work fine when I apply them myself. This is what I need to do next, define an array of the functions:
var arrOfFuncs = [UC , DC]
and then, given a number such as 10110, perform upon "cubePos" the equivalent of:
DC
UC
DC
DC
UC
When I put something like:
arrOfFuncs[0]
I would expect the code to apply UC() to the array "cubePos", but nothing seems to happen at all, despite UC () working fine when typed manually into the code.
Hoping someone can help!
You haven't posted the code you are using in your question, so I created a basic sample which works. You can try using below code.
func one() {
print("Hello 1")
}
func two() {
print("Hello 2")
}
let arr = [one, two]
arr[0]
"10101".forEach {
arr[Int(String($0))!]()
}

protobuf-c: How to pack nested messages

I have a Protobuf Protocol file that looks something like this:
message Foo {
message Bar {
required string name = 1;
required string value = 2;
}
message Baz {
required Bar a = 1;
}
}
Given this protocol file, I need to write an encoder using protobuf-c, the C extension for Protobuf. I wrote the following code:
Foo myfoo = FOO__INIT;
Foo__Bar mybar = FOO__BAR__INIT;
Foo__Baz mybaz = FOO__BAZ__INIT;
mybaz.a = &mybar;
However, I am stuck at this point on how to serialize mybaz. The generated struct for Foo, does not contain any entry that I can assign mybaz to. And no method for generated to directly pack Baz.
In Python, this was a lot more simpler, since a mybaz.SerializeToString() function had been generated. How should I go about this in C?
Declaring nested types in Protocol Buffers is like declaring nested classes in C++ or static inner classes in Java. This simply declares a new type; it does not add a field to the outer type. So, in your proto schema, Foo is a completely empty message -- it has no fields. This is true regardless of which programming language you're working in.
Probably what you meant to do is something like this:
message Foo {
message Bar {
required string name = 1;
required string value = 2;
}
message Baz {
required Bar a = 1;
}
optional Baz baz = 1;
}
Now Foo has a field called baz into which you can assign a Baz object.

Token return values in ANTLR 3 C

I'm new to ANTLR, and I'm attempting to write a simple parser using C language target (antler3C). The grammar is simple enough that I'd like to have each rule return a value, eg:
number returns [long value]
:
( INT {$value = $INT.ivalue;}
| HEX {$value = $HEX.hvalue;}
)
;
HEX returns [long hvalue]
: '0' 'x' ('0'..'9'|'a'..'f'|'A'..'F')+ {$hvalue = strtol((char*)$text->chars,NULL,16);}
;
INT returns [long ivalue]
: '0'..'9'+ {$ivalue = strtol((char*)$text->chars,NULL,10);}
;
Each rule collects the return value of it's child rules until the topmost rule returns a nice struct full of my data.
As far as I can tell, ANTLR allows lexer rules (tokens, eg 'INT' & 'HEX') to return values just like parser rules (eg 'number'). However, the generated C code will not compile:
error C2228: left of '.ivalue' must have class/struct/union
error C2228: left of '.hvalue' must have class/struct/union
I did some poking around, and the errors make sense - the tokens end up as generic ANTLR3_COMMON_TOKEN_struct, which doesn't allow for a return value. So maybe the C target just doesn't support this feature. But like I said, I'm new to this, and before I go haring off to find another approach I want to confirm that I can't do it this way.
So the question is this: 'Does antler3C support return values for lexer rules, and if so what is the proper way to use them?'
Not really any new information, just some details on what #bemace already mentioned.
No, lexer rules cannot have return values. See 4.3 Rules from The Definitive ANTLR reference:
Rule Arguments and Return Values
Just like function calls, ANTLR parser and tree parser rules can have
arguments and return values. ANTLR lexer rules cannot have return
values [...]
There are two options:
Option 1
You can do the transforming to a long in the parser rule number:
number returns [long value]
: INT {$value = Long.parseLong($INT.text);}
| HEX {$value = Long.parseLong($HEX.text.substring(2), 16);}
;
Option 2
Or create your own token that has, say, a toLong(): long method:
import org.antlr.runtime.*;
public class YourToken extends CommonToken {
public YourToken(CharStream input, int type, int channel, int start, int stop) {
super(input, type, channel, start, stop);
}
// your custom method
public long toLong() {
String text = super.getText();
int radix = text.startsWith("0x") ? 16 : 10;
if(radix == 16) text = text.substring(2);
return Long.parseLong(text, radix);
}
}
and define in the options {...} header in your grammar to use this token and override the emit(): Token method in your lexer class:
grammar Foo;
options{
TokenLabelType=YourToken;
}
#lexer::members {
public Token emit() {
YourToken t = new YourToken(input, state.type, state.channel,
state.tokenStartCharIndex, getCharIndex()-1);
t.setLine(state.tokenStartLine);
t.setText(state.text);
t.setCharPositionInLine(state.tokenStartCharPositionInLine);
emit(t);
return t;
}
}
parse
: number {System.out.println("parsed: "+$number.value);} EOF
;
number returns [long value]
: INT {$value = $INT.toLong();}
| HEX {$value = $HEX.toLong();}
;
HEX
: '0' 'x' ('0'..'9'|'a'..'f'|'A'..'F')+
;
INT
: '0'..'9'+
;
When you generate a parser and lexer, and run this test class:
import org.antlr.runtime.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("0xCafE");
FooLexer lexer = new FooLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
FooParser parser = new FooParser(tokens);
parser.parse();
}
}
it will produce the following output:
parsed: 51966
The first options seems the more practical in your case.
Note that, as you can see, the examples given are in Java. I have no idea if option 2 is supported in the C target/runtime. I decided to still post it to be able to use it as a future reference here on SO.
Lexer rules must return Token objects, because that's what the Parser expects to work with. There may be a way to customize the type of token object used, but it's easier just to convert tokens to values in the lowest-level parser rules.
social_title returns [Name.Title title]
: SIR { title = Name.Title.SIR; }
| 'Dame' { title = Name.Title.DAME; }
| MR { title = Name.Title.MR; }
| MS { title = Name.Title.MS; }
| 'Miss' { title = Name.Title.MISS; }
| MRS { title = Name.Title.MRS; };
There is a third option: You can pass an object as argument to the lexer rule. This object contains a member that represents the lexer's return value. Within the lexer rule, you can set the member. Outside the lexer rule, at the point you call it, you can get the member and do whatever you want with this 'return value'.
This way of parameter passing corresponds to the 'var' parameters in Pascal or the 'out' parameters in C++ and other programming languages.

Resources