1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008 Henrik Tidefelt
21 #include "Shapes_Helpers_decls.h"
23 #include "shapescore.h"
24 #include "continuations.h"
26 #include "texlabelmanager.h"
27 #include "shapesexceptions.h"
29 using namespace Shapes
;
37 class Core_TeX
: public Lang::CoreFunction
40 Core_TeX( const char * title
)
41 : CoreFunction( title
)
44 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
46 const size_t ARITY
= 1;
47 CHECK_ARITY( args
, ARITY
, title_
);
49 typedef const Lang::String ArgType
;
50 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 0, callLoc
);
52 Kernel::ContRef cont
= evalState
->cont_
;
53 cont
->takeValue( Kernel::theTeXLabelManager
.request( std::string( arg
->val_
.getPtr( ) ), args
.getLoc( 0 ), evalState
->dyn_
),
58 class Core_Unicode
: public Lang::CoreFunction
61 Core_Unicode( const char * title
)
62 : CoreFunction( title
)
65 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
67 const size_t ARITY
= 1;
68 CHECK_ARITY( args
, ARITY
, title_
);
71 typedef const Lang::Integer ArgType
;
72 ArgType::ValueType arg
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, argsi
, callLoc
)->val_
;
75 throw Exceptions::CoreOutOfRange( title_
, args
, argsi
, "Unicode code points cannot be negative." );
78 Kernel::ContRef cont
= evalState
->cont_
;
79 cont
->takeValue( Kernel::ValueRef( new Lang::Character( arg
) ),
84 class Core_coords2D
: public Lang::CoreFunction
87 Core_coords2D( const char * title
)
88 : CoreFunction( title
)
91 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
93 const size_t ARITY
= 2;
94 CHECK_ARITY( args
, ARITY
, title_
);
96 RefCountPtr
< const Lang::Value
> xUntyped
= args
.getValue( 0 );
97 RefCountPtr
< const Lang::Value
> yUntyped
= args
.getValue( 1 );
100 typedef const Lang::Float ArgType
;
101 ArgType
* xVal
= dynamic_cast< ArgType
* >( xUntyped
.getPtr( ) );
104 ArgType
* yVal
= dynamic_cast< ArgType
* >( yUntyped
.getPtr( ) );
107 if( xVal
->val_
== 0 )
109 /* This is a special case, where 0 is interpreted as a length.
111 typedef const Lang::Length ArgTypeY
;
112 ArgTypeY
* yVal
= dynamic_cast< ArgTypeY
* >( yUntyped
.getPtr( ) );
115 Kernel::ContRef cont
= evalState
->cont_
;
116 cont
->takeValue( Kernel::ValueRef( new Lang::Coords2D( Lang::Length( 0 ), *yVal
) ),
121 throw Exceptions::CoreTypeMismatch( callLoc
, "(<>, y )", args
, 1, ArgType::staticTypeName( ) );
124 Kernel::ContRef cont
= evalState
->cont_
;
125 cont
->takeValue( Kernel::ValueRef( new Lang::FloatPair( xVal
->val_
, yVal
->val_
) ),
132 typedef const Lang::Length ArgType
;
133 ArgType
* xVal
= dynamic_cast< ArgType
* >( xUntyped
.getPtr( ) );
136 ArgType
* yVal
= dynamic_cast< ArgType
* >( yUntyped
.getPtr( ) );
139 /* A Float with value 0 is still allowed
141 typedef const Lang::Float ArgTypeY
;
142 ArgTypeY
* yVal
= dynamic_cast< ArgTypeY
* >( yUntyped
.getPtr( ) );
145 if( yVal
->val_
== 0 )
147 Kernel::ContRef cont
= evalState
->cont_
;
148 cont
->takeValue( Kernel::ValueRef( new Lang::Coords2D( *xVal
, Lang::Length( 0 ) ) ),
153 throw Exceptions::CoreTypeMismatch( callLoc
, "(<>, y )", args
, 1, ArgType::staticTypeName( ) );
156 Kernel::ContRef cont
= evalState
->cont_
;
157 cont
->takeValue( Kernel::ValueRef( new Lang::Coords2D( *xVal
, *yVal
) ),
163 throw Exceptions::CoreTypeMismatch( callLoc
, "( x ,<>)", args
, 0, Helpers::typeSetString( Lang::Float::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
167 class Core_cornercoords2D
: public Lang::CoreFunction
170 Core_cornercoords2D( const char * title
)
171 : CoreFunction( title
)
174 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
177 * We don't check for presence of named arguments here since this function is generally called internally, and
178 * we don't want the extra overhead of an unnecessary check.
181 Kernel::ContRef cont
= evalState
->cont_
;
182 switch( args
.size( ) )
185 cont
->takeValue( Kernel::ValueRef( new Lang::CornerCoords2D( * Helpers::down_cast_CoreArgument
< const Lang::Length
>( "( x, <> ^ )", args
, 0, callLoc
),
186 * Helpers::down_cast_CoreArgument
< const Lang::Length
>( "( <>, y ^ )", args
, 1, callLoc
),
187 std::numeric_limits
< double >::signaling_NaN( ) ) ),
191 cont
->takeValue( Kernel::ValueRef( new Lang::CornerCoords2D( * Helpers::down_cast_CoreArgument
< const Lang::Length
>( "( x, <> ^ <> )", args
, 0, callLoc
),
192 * Helpers::down_cast_CoreArgument
< const Lang::Length
>( "( <>, y ^ <> )", args
, 1, callLoc
),
193 Helpers::down_cast_CoreArgument
< const Lang::Float
>( "( <>, <> ^ a )", args
, 2, callLoc
)->val_
) ),
197 throw Exceptions::CoreArityMismatch( title_
, 2, 3, args
.size( ) );
203 class Core_coords3D
: public Lang::CoreFunction
206 Core_coords3D( const char * title
)
207 : CoreFunction( title
)
210 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
212 const size_t ARITY
= 3;
213 CHECK_ARITY( args
, ARITY
, title_
);
215 RefCountPtr
< const Lang::Value
> xUntyped
= args
.getValue( 0 );
216 RefCountPtr
< const Lang::Value
> yUntyped
= args
.getValue( 1 );
217 RefCountPtr
< const Lang::Value
> zUntyped
= args
.getValue( 2 );
220 typedef const Lang::Float ArgType
;
221 ArgType
* xVal
= dynamic_cast< ArgType
* >( xUntyped
.getPtr( ) );
224 Kernel::ContRef cont
= evalState
->cont_
;
225 cont
->takeValue( Kernel::ValueRef( new Lang::FloatTriple( xVal
->val_
,
226 Helpers::down_cast_CoreArgument
< ArgType
>( "(<>, y ,<>)", args
, 1, callLoc
)->val_
,
227 Helpers::down_cast_CoreArgument
< ArgType
>( "(<>,<>, z )", args
, 2, callLoc
)->val_
) ),
234 typedef const Lang::Length ArgType
;
235 ArgType
* xVal
= dynamic_cast< ArgType
* >( xUntyped
.getPtr( ) );
238 Kernel::ContRef cont
= evalState
->cont_
;
239 cont
->takeValue( Kernel::ValueRef( new Lang::Coords3D( *xVal
,
240 * Helpers::down_cast_CoreArgument
< ArgType
>( "(<>, y ,<>)", args
, 1, callLoc
),
241 * Helpers::down_cast_CoreArgument
< ArgType
>( "(<>,<>, z )", args
, 2, callLoc
) ) ),
247 throw Exceptions::CoreTypeMismatch( callLoc
, "( x ,<>,<>)", args
, 0, Helpers::typeSetString( Lang::Float::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
251 class Core_polarHandle2DFree_r
: public Lang::CoreFunction
254 Core_polarHandle2DFree_r( const char * title
)
255 : CoreFunction( title
)
258 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
260 const size_t ARITY
= 1;
261 CHECK_ARITY( args
, ARITY
, title_
);
263 Kernel::ContRef cont
= evalState
->cont_
;
264 cont
->takeValue( Kernel::ValueRef( new Lang::PolarHandle2DFree_r( evalState
->dyn_
->getDefaultUnit( ),
265 Helpers::down_cast_CoreArgument
< const Lang::Float
>( "(^ a )", args
, 0, callLoc
)->val_
) ),
270 class Core_polarHandle2DFree_ra
: public Lang::CoreFunction
273 Core_polarHandle2DFree_ra( const char * title
)
274 : CoreFunction( title
)
277 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
279 const size_t ARITY
= 0;
280 CHECK_ARITY( args
, ARITY
, title_
);
282 Kernel::ContRef cont
= evalState
->cont_
;
283 cont
->takeValue( Kernel::ValueRef( new Lang::PolarHandle2DFree_ra( evalState
->dyn_
->getDefaultUnit( ) ) ),
293 RefCountPtr
< const Lang::CoreFunction
> Ast::THE_FUNCTION_coords2D( new Lang::Core_coords2D( "coords" ) );
294 RefCountPtr
< const Lang::CoreFunction
> Ast::THE_FUNCTION_cornercoords2D( new Lang::Core_cornercoords2D( "cornercoords" ) );
295 RefCountPtr
< const Lang::CoreFunction
> Ast::THE_FUNCTION_coords3D( new Lang::Core_coords3D( "coords3D" ) );
296 RefCountPtr
< const Lang::CoreFunction
> Ast::THE_FUNCTION_polarHandle2DFree_r( new Lang::Core_polarHandle2DFree_r( "polarHandleFree_r" ) );
297 RefCountPtr
< const Lang::CoreFunction
> Ast::THE_FUNCTION_polarHandle2DFree_ra( new Lang::Core_polarHandle2DFree_ra( "polarHandleFree_ra" ) );
298 /* This belongs in consts.cc but we must make sure it is initialized before we use it below. Note that the identifier will actually be destroyed
299 * before Ast::THE_FUNCTION_TeX is destroyed, but that should not cause a failure...
301 RefCountPtr
< const char > Lang::TEX_SYNTAX_ID
= strrefdup( "TeX" );
302 RefCountPtr
< const Lang::CoreFunction
> Ast::THE_FUNCTION_TeX( new Lang::Core_TeX( Lang::TEX_SYNTAX_ID
.getPtr( ) ) );
303 RefCountPtr
< const Lang::CoreFunction
> Ast::THE_FUNCTION_Unicode( new Lang::Core_Unicode( "Unicode" ) );