• 3.8MB weixin_42683394 2021-09-30 06:37:45
• 52KB weixin_38686187 2020-12-21 13:05:42
• ## solo-lisp:[废弃] [wip]普通语言和可读的javascript语言的最小lisp语法-源码 JavaScript

16KB weixin_42126668 2021-04-29 06:18:34
• 28KB weixin_42166623 2021-02-04 03:14:27
• 给定一个类似 Lisp 语句的表达式 expression，求出其计算结果。 表达式语法如下所示: 表达式可以为整数，let 语法，add 语法，mult 语法。表达式的结果总是一个整数。(整数可以是正整数、负整数、0) let 语法表示为...
给定一个类似 Lisp 语句的表达式 expression，求出其计算结果。 表达式语法如下所示:
表达式可以为整数，let 语法，add 语法，mult 语法。表达式的结果总是一个整数。(整数可以是正整数、负整数、0)let 语法表示为 (let v1 e1 v2 e2 … vn en expr), 其中 let语法总是以字符串 "let"来表示，接下来会跟随一个或多个交替变量或表达式，也就是说，第一个变量 v1被分配为表达式 e1 的值，第二个变量 v2 被分配为表达式 e2 的值，以此类推；最终 let 语法的值为 expr表达式的值。add语法表示为 (add e1 e2)，其中 add 语法总是以字符串 "add"来表示，该语法总是有两个表达式e1、e2, 该语法的最终结果是 e1 表达式的值与 e2 表达式的值之和。mult语法表示为 (mult e1 e2) ，其中 mult 语法总是以字符串"mult"表示， 该语法总是有两个表达式 e1、e2，该语法的最终结果是 e1 表达式的值与 e2 表达式的值之积。在该题目中，变量的命名以小写字符开始，之后跟随0个或多个小写字符或数字。为了方便，“add”，“let”，“mult"会被定义为"关键字”，不会在表达式的变量命名中出现。
最后，要说一下范围的概念。在做计算时，需要注意优先级，在最内层(根据括号)的表达式的值应该先计算,然后依次计算外层的表达式。我们将保证每一个测试的表达式都是合法的。有关范围的更多详细信息，请参阅示例。
示例:
输入: (add 1 2)
输出: 3
输入: (mult 3 (add 2 3))
输出: 15
输入: (let x 2 (mult x 5))
输出: 10
输入: (let x 2 (mult x (let x 3 y 4 (add x y))))
输出: 14
解释:
表达式 (add x y), 在获取 x 值时, 我们应当由最内层依次向外计算, 首先遇到了 x=3, 所以此处的 x 值是 3.
输入: (let x 3 x 2 x)
输出: 2
解释: let 语句中的赋值运算按顺序处理即可
输入: (let x 1 y 2 x (add x y) (add x y))
输出: 5
解释:
第一个 (add x y) 计算结果是 3，并且将此值赋给了 x 。
第二个 (add x y) 计算结果就是 3+2 = 5 。
输入: (let x 2 (add (let x 3 (let x 4 x)) x))
输出: 6
解释:
(let x 4 x) 中的 x 的作用范围仅在()之内。所以最终做加法操作时，x 的值是 2 。
输入: (let a1 3 b2 (add a1 1) b2)
输出: 4
解释:
变量命名时可以在第一个小写字母后跟随数字.

注意:
我们给定的 expression 表达式都是格式化后的：表达式前后没有多余的空格，表达式的不同部分(关键字、变量、表达式)之间仅使用一个空格分割，并且在相邻括号之间也没有空格。我们给定的表达式均为合法的且最终结果为整数。
我们给定的表达式长度最多为 2000 (表达式也不会为空，因为那不是一个合法的表达式)。
最终的结果和中间的计算结果都将是一个 32 位整数。

首先介绍表达式的可能情况：
第一种：表达式是"(...)"，按照三种基本操作递归处理得到表达式的值。

下面是三种基本操作：
第二种：(mult e1 e2)，处理mult，我们先处理e1、e2两个表达式，得到e1、e2两个表达式的值，进行乘法法计算，得到当前expression的值。
第三种：(let v1 e1 v2 e2 ... vn en expr)，对于（v1 e1）,（v2，e2）,（v3，e3）, ... , （v n - 1，e n - 1）,（v n，e n）这都是赋值操作，对于e1到en共n个表达式，我们分别求出这n个表达式的值，然后赋值到n个变量v1到vn即可，最后求出表达式expr的值就是当前expression的值。

class Solution {
public:
int evaluate(string expression) {
int nowIndex = 1;//即将处理的字符串下标，初始化为1，因为每个输入都有一个外加括号
unordered_map<string, int> hashMap;//用于储存这个表达式中let赋值操作
return myEvaluate(expression, nowIndex, hashMap);//开始处理一个expression
}
//开始处理以nowIndex为起始的一个expression
int myEvaluate(string &expression, int &nowIndex, unordered_map<string, int> hashMap){
if (expression[nowIndex] == 'a'){
int firstNum = 0, secondNum = 0;
if (expression[nowIndex] == '('){//第一个表达式也是"(...)"，递归处理
nowIndex += 1;//跳过左括号
firstNum = myEvaluate(expression, nowIndex, hashMap);
}
else{//否则这个表达式是变量或者常量（表达式只有三种可能）
firstNum = myFunc(expression, nowIndex, hashMap);
}
nowIndex += 1;//跳过空格
if (expression[nowIndex] == '('){//第二个表达式也是"(...)"，递归处理
nowIndex += 1;//跳过左括号
secondNum = myEvaluate(expression, nowIndex, hashMap);
}
else{//否则这个表达式是变量或者常量（表达式只有三种可能）
secondNum = myFunc(expression, nowIndex, hashMap);
}
nowIndex += 1;//跳过右括号
return firstNum + secondNum;//进行加法操作
}
else if (expression[nowIndex] == 'm'){
//第二种情况：处理mult操作
int firstNum = 0, secondNum = 0;
nowIndex += 5;//跳过"mult "
//第一步：求mult的第一个表达式参数的值
if (expression[nowIndex] == '('){//第一个表达式也是"(...)"，递归处理
nowIndex += 1;//跳过左括号
firstNum = myEvaluate(expression, nowIndex, hashMap);
}
else{//否则这个表达式是变量或者常量（表达式只有三种可能）
firstNum = myFunc(expression, nowIndex, hashMap);
}
nowIndex += 1;//跳过空格
//第二步：求mult的第二个表达式参数的值
if (expression[nowIndex] == '('){//第二个表达式也是"(...)"，递归处理
nowIndex += 1;//跳过左括号
secondNum = myEvaluate(expression, nowIndex, hashMap);
}
else{//否则这个表达式是变量或者常量（表达式只有三种可能）
secondNum = myFunc(expression, nowIndex, hashMap);
}
nowIndex += 1;//跳过右括号
return firstNum * secondNum;//进行乘法操作
}
else {
//第三种情况：处理let操作(let v1 e1 v2 e2 ... vn en expr)
//我们每次成对进行处理（v1 e1）,（v2，e2）,（v3，e3）, ... , （v n - 1，e n - 1）,（v n，e n），最后单出expr
nowIndex += 4;//跳过"let "
while (true){
if (expression[nowIndex] == '('){
//let中的expr也是一个"(...)"，递归处理
nowIndex += 1;
int tempRes = myEvaluate(expression, nowIndex, hashMap);
nowIndex += 1;//跳过右括号
return tempRes;
}
//下面将会每次处理一个变量一个表达式
string str = "";
while (expression[nowIndex] != ')' && expression[nowIndex] != ' '){
str += expression[nowIndex++];
}
if (expression[nowIndex] == ')'){
//遇到了右括号，则说明最后一个expr表达式是常量或者变量
nowIndex += 1;
if (hashMap.count(str)){
return hashMap[str];
}
else{
return atoi(str.c_str());
}
}
else{
//否则读取一个(变量 表达式)进行赋值操作
nowIndex += 1;
if (expression[nowIndex] == '('){//e n表达式也是"(...)"，递归处理
nowIndex += 1;//跳过右括号
hashMap[str] = myEvaluate(expression, nowIndex, hashMap);
}
else{//e n表达式是变量或者常量（表达式只有三种可能）
hashMap[str] = myFunc(expression, nowIndex, hashMap);
}
nowIndex += 1;
}
}
}
}
//读取nowIndex为起始下标的一个表达式（这个表达式是常量比如2，或者是一个在hashMap中的变量）
int myFunc(string &expression, int &nowIndex, unordered_map<string, int> &hashMap){
string str = "";
while (expression[nowIndex] != ' ' && expression[nowIndex] != ')'){
str += expression[nowIndex++];
}
if (hashMap.count(str)){//是一个在hashMap中的变量
return hashMap[str];
}
else{//表达式是常量比如2
return atoi(str.c_str());
}
}
};

这种题目一般都不是很难，就是细节处理需要严密的逻辑以及清新的思路。
展开全文
qq_41855420 2019-05-01 17:54:39
• 有数字（0~9构成的正整数）、三种操作运算符...语法树结束后，后面加任何字符都是合法的，比如(+ (* 2 3)(^4)))))))#$是合法的 匆匆忙忙地写了一个，感觉太长了。。。应该有很大的优化空间。 主要思路：用一个va... 有数字（0~9构成的正整数）、三种操作运算符（加法+、乘法*、自增^）、分隔符一个空格、左右括号 表达式形式是“(运算符 参数)”形式 比如(+ 3 4)，求值结果7；(+ (* 2 3)(^4))求值结果11 语法树结束后，后面加任何字符都是合法的，比如(+ (* 2 3)(^4)))))))#$是合法的
匆匆忙忙地写了一个，感觉太长了。。。应该有很大的优化空间。
主要思路：用一个var类保存操作数，包括操作符和数字（存在联合体中，用一个枚举变量表示类型），然后遍历输入的字符串，将左括号、数字、操作符压入计算栈，当遇到右括号时，弹出数字和操作符进行计算，并弹出左括号，将结果压入。如果压入结果之后，计算栈大小为1，说明语法树结束啦，直接跳出。中间任何操作失败，都跳出输出-1，主要是这个的判断占了很大篇幅，得想办法优化。
#include <iostream>
#include <string>
#include <stack>
#include <unordered_set>
using namespace std;
struct var {
union {
int num;
char op;
};
enum class type {ch,number} ty;
var(int n, type t=type::number) :num(n), ty(t) {}
var(char c, type t= type::ch) :op(c), ty(t) {}
};
using vtype = var::type;
unordered_set<char> ops = { '+','*','^' };
int main() {
string exp;
while (getline(cin,exp)) {
stack<var> cal;
bool valid =true;
for (auto i = exp.cbegin(); i != exp.cend() && valid;++i) {
if (*i >= '0' && *i <= '9') {//数字
int num = *i++ - '0';
while (i!=exp.cend() &&*i >= '0' && *i <= '9') {
num = num * 10 + *i++ - '0';
}
if (i == exp.cend()) {
valid = false;
break;
}
else
cal.emplace(num);
}
if (*i == '(' || ops.find(*i) != ops.end())//左括号或者操作符
cal.emplace(*i);
else if (*i == ')') {//有右括号就弹出东西来计算，如果不对就是不合法的
bool dual;
if (cal.empty() || cal.top().ty != vtype::number) {
valid = false;
break;
}
int rhs = cal.top().num;
int lhs;
int res;
cal.pop();
if (cal.empty()) {
valid = false;
break;
}
if (cal.top().ty == vtype::number) {
dual = true;
lhs = cal.top().num;
cal.pop();
} else if (cal.top().op == '^') {
cal.pop();
res = ++rhs;
dual = false;
} else {
valid = false;
}
if (dual) {
if (!cal.empty() && cal.top().ty == vtype::ch) {
char op = cal.top().op;
cal.pop();
if (op == '+')res = lhs + rhs;
else res = lhs * rhs;
} else {
valid = false;
}
}
if (!cal.empty() && cal.top().ty == vtype::ch && cal.top().op == '(') {
cal.pop();
cal.emplace(res);
} else {
valid = false;
}
if (cal.size() == 1 && cal.top().ty == vtype::number)break;//语法树结束
} else if (*i == ' ')continue;
else {
if (cal.size() == 1 && cal.top().ty == vtype::number)//非法字符，但是语法树已结束
break;
else valid = false;
}
}
if (valid && cal.size() == 1 && cal.top().ty == vtype::number) {
cout << cal.top().num << endl;
}
else cout << -1<<endl;
}
return 0;
}

展开全文
sinat_39088557 2018-08-15 22:18:06
• ## lisplate:基于类Lisp语法JavaScript功能模板引擎-源码 JavaScript

115KB weixin_42104778 2021-05-09 10:49:45
• This tutorial is aimed at the AutoCAD users who would like to start learning AutoLisp. I suggest that you go through this tutorial along with the AutoCAD Programmers Reference Guide. You...

Introduction
This tutorial is aimed at the AutoCAD users who would like to start learning AutoLisp. I suggest that you go through this tutorial along with the AutoCAD Programmers Reference Guide. You can then lookup the relevant AutoLisp commands for a more detailed explanation. Hope this helps you and Good Luck in your Lisping - Kenny Ramage
Principles of Programming
All AutoLisp programs must contain the suffix ".LSP" otherwise AutoCAD will not access them when loading. (eg. CHTEXT.LSP).

Use a simple text processor such as Notepad to create and edit your lisp files.
Function (which is simply the program)
Is a pre-defined set of instructions that describes a set of actions that AutoLisp is to perform, divided into three sections:
OPERATOR - Getting input.ARGUMENT - Manipulating the input.COMMAND - Using the manipulated input.
Charting
Draw out or write out in English what you want your program to do.
Variables
These are like empty boxes in which to store data, to be used later. In AutoLisp, variables may be a collection of letters or numbers as long as they begin with the letters.
Example of legal variables are as follows:
AARC1POINT1PNT1D3
An AutoLisp variable may contain more than one value in a single variable. A value can be anything, such as :
Real numberStringIntegerPickset
Therefore a variable can store just about anything.
Structuring
Structure your program in such a way that it is easy to understand, by yourself and everyone else. e.g. Keep input statements together. Keep your arguments together. Keep your commands together. Track your work with the semicolon. When you begin a line with a semicolon, anything you write after will be ignored by AutoLisp. It is used for documentation and explanation of your program. Write notes about your program, what you are doing and what the variables are. A semicolon does not have to begin the line.
(prompt "This line will print"); This is a comment
From where the semicolon begins, the remainder of the line is a comment statement.
Parentheses ( )
Parentheses are vital to writing AutoLisp programs. All commands are surrounded by parentheses. AutoLisp uses parentheses to nest, allowing you to write a command that acts on (evaluates) another command. In turn, that command can act on another. As you add parentheses, you're nesting commands become deeper and deeper. Remember to come out of the nest with an equal number of parentheses.
Note: Always close what you open.
Defun (Define Function)
In AutoLisp the name of the program or function must be defined in the first statement, which is done by using the command:
(defun functionname ()
body of program
)
Defun is the first actual command and is followed by the name of the function (or program). Defun encloses the entire program and its closing bracket comes after the main body of the program There are different ways of starting a function for example:
(defun drawline ()The first way, you are saying that all variables you plan to use in the program are GLOBAL, which are variables that do not lose their value after the program ends.(defun drawline (/ pntl pnt2)The second way, you are saying that the variables you are using are LOCAL variables, which are variables that have value only for that program and while that program is running.(defun C:drawline ()The third way, as the first BUT the C: tells AutoCAD to treat that function as any other AutoCAD command.(defun C:drawline (/ pntl pnt2)The fourth way, as the second, but an AutoCAD command.(defun drawline (a / pntl pnt2)The last, variable a receives the first value to it from outside the program.
Data Types
IntegersAre numbers ranging between -32768 and +32767 without decimal points eg: 1
RealsAre numbers with a decimal point eg: 1.0
StringsStrings are bits of text and can be up to a maximum length of 100 characters eg: Point 1
ListsA list is a variable that has more than one element. A point in your drawing is described by the value of the X co-ordinate and the value of the Y co-ordinate. In AutoLisp, that point can be described by a single variable, a list of two elements, the first being the X value and the second being the Y value eg: ( 7 10 ). The following are also examples of lists: ( 5 9 7 2 ) and ( 1.5 2.3 4.9 ).
AtomsIf a variable has a single indivisible value it is an atom. For example, each element in the lists above is an atom e.g. 6 or A
The type function will return the data type of a variable. For example:
(type "My name")
Will return STR meaning "string". In fact, you can try this for yourself now. Type the code above at the AutoCAD command prompt and hit enter.

Input Commands (getting info from the user)
AutoLisp provides a number of options for getting different types of data from the user.
Input CommandsgetpointNeeds you to pick a point on the screen.getintNeeds an Integer eg: 1.getrealNeeds a real number eg: 10.00.getcornerNeeds a second point on the screen and draws an elastic window from a previous point.getstringNeeds a string of text.getdistNeeds a value either by picking on the screen or a number from the keyboard.getangleNeeds an angle either by pointing on the screen or by typing an angle, which will be returned in radians.getkwordNeeds a keyword from the user.getvarWill get the value of an AutoCAD system variable.initgetEstablishes various options for use by the next getxxx function.getorientIs similar to the GETANGLE but is affected by the zero-degree base and the direction. It will always give you the absolute angle using 0 degree base as EAST.
Input Command Examples
In each of the following examples, enter the code at the AutoCAD prompt to see what happens.
(getpoint "\nPick a POINT on the screen:") Pick a point when prompted and AutoCAD will return the value (X Y Z) of that point.
Tip:\n is a special escaped character that takes you to the next line (like a carriage return). The forward slash character tells AutoLisp to interpret the following character as a special character rather than just as a letter "n". The "n" must be always be lower case. The use of "\n" is purely cosmetic (it doesn't change the way the program works) but it does make everything much easier to read for the user by starting each prompt on a new line.
Caution: Your prompt must always be between quotes, "prompt" otherwise you will get an error.
(getint "\nEnter your age :") Type an integer (such as 34) and AutoLisp will return that number.(getreal "\nEnter a number :") Type a real number (such as 10.51) and AutoLisp will return that number.(getcorner pnt1 "\nPick second point :") Will create an elastic window from the variable called "pnt1", which must already be defined.(getstring "\nWhat is the day today? :") Type some text and Autolisp will return that text.Or…(getstring T "\nWhat is your full name? :") This prompt allows you to enter a string of words separated by spaces. Ordinarily, AutoCAD will interpret a space in the same way it interprets a carriage return. The T is a special AutoLisp symbol that means "true" it is used to allow spaces in string input. In fact, you can use any positive integer (such as 1) in place of T but the T symbol helps to make the code more understandable.(getdist "\nHow long is the line? :") Pick two points or type a length and AutoLisp will return that length.(getangle "\nWhat is the angle? :") Pick two points for the angle or type an angle and AutoLisp will return that angle in radians.(initget 1 "Yes NO")(getkword "\nAre you going? (Yes or NO):") Initget will control the next getxxx function and is used to specify a list of valid options or keywords, getkword will accept only one of the words specifies using initget. In this case, the options are "Yes" or "No". The 1 is an initget bitcode and it means that a null response is not allowed. See the section below for more details.
Tip: Just as in native AutoCAD commands, any valid option keyword can be entered simply by typing the upper case part of the keyword. So, in the example above, to answer Yes to the prompt, you need only type "y" but to answer NO, you must type "no". This is used to avoid potential ambiguities when 2 or more options begin with the same letter.
(getvar "FILLETRAD") Would return the set value of the FILLETRAD system variable (fillet radius) eg : 0. 5(getorient "\nWhat is the angle? :") Pick two points for the angle or type an angle and AutoLisp will return an angle in radians relative to 0 degrees at East.
Initget Bit Codes
The number 1 after the initget function in code example 8, above is known as an initget bit code. Initget bit codes can be used to control what type of inputs are allowed. In this example, 1 is used to disallow a null input. This forces the user to enter one of the specified option keywords rather than just hitting carriage return.
Initget Bit Codes1Disallow null input.2Disallow zero values.4Disallow negative values.8DO not check limits, even if LIMECHECK is on.16Return 3D points rather than 2D points.32Use dashed lines when drawing rubber band or box.
Example:
(initget (+ 1 2 4))(getint "\nHow old are you?:")
Will only accept a positive, non-zero Integer eg: 21
Setq Command
Short for (Set Equal) or make one thing equal to another.
(setq) is an assignment command, eg : it assigns the value of one variable or constant to another variable.
Note: (setq) is the primary assignment command in AutoLisp. The "=" (equals character) is not used as an assignment in AutoLisp. The equals character is used, but only as a non assignment statement. It does not have the ability to make one variable equal to another as it does in some other programming languages (it is used for a comparison of variables, numbers or strings).
(setq a b)This statement assigns the value of b to the variable a so that a becomes the same as b and b is unchanged.
Note: The first variable after the (setq) is the one that receives the value. Watch out for this because it is a potential cause of confusion.
Print Commands
Prompt
(prompt "Maybe you need a rest")
This command is used simply to print a message on the command line. A line feed (\n) is not included so two consecutive prompt commands will print both messages on the same line and without any spaces between them. Therefore, any printing after the prompt must be preceeded by the (terpri) function or \n.
Terpri
This is a line feed that causes the next printed text to appear on the next line. It generally follows the prompt command. eg:
(prompt "Hello, how are you?")(terpri)or(prompt "\nHello, how are you?")
Prin1
This function prints the expression on the screen and returns the expression. It can be any expression and need not only be a string. The expression can also be written to a file and will appear in the file exactly as it would on the screen.
(prin1 "Hello") would print "Hello".
(prin1 a) would print the value of variable a.
(prin1 a f) would print the value of variable a to an open file named in variable f.
Princ
Is the same as prin1 except that the control characters ("") are not printed. Can also be used to print a blank line by using no statement after princ.
(princ "Hello") would print Hello.
Print
Same as prin1 except that a new line is printed before the expression and a space is printed after the expression.
Setvar
This function sets an AutoCAD system variable to a given value and returns that value. The variable name must be in double quotes. eg:
(setvar "blipmode" 0) returns 0 and will switch blipmode off. 1 would switch it on again.
Doing Arithmetic
AutoLisp provides a number of arithmetic functions and although the format of these functions is consistent with other AutoLisp functions (function first, followed by values), it is not one we are familiar with from school. The important thing to remember is that the order of the values is consistent with what we already know. In other words (/ 27 3) is the same as 27 divided by 3.
(+ 1 1) returns 2.
(- 2 1) returns 1.
(* 2 2) returns 4.
(/ 2 1) returns 2.
(1+ 1) returns 2 (Incremented).
(1- 2) returns 1 (Decremented).
Polar
This function returns the point at an angle (in radians) and distance from a given point.
(polar pnt1 ang1 dist1) where pnt1, ang1 and dist1 are 3 previously assigned variables.
Inters
Examines two lines and returns the point where they intersect even if they do not physically cross one another.
(inters pnt1 pnt2 pnt3 pnt4) where pnt1 and pnt2 are the end points of one line and pnt3 and pnt4 are the end points of another.
Any AutoCAD command can be used inside your lisp program BUT one must remember that they have to be used exactly as you would in AutoCAD and your RETURN is a double set of Quotes (""). eg:
(command "line" pnt1 pnt2 "") draws a line from pnt1 to pnt2 and the "" acts as a return to terminate the command.
Not all commands require termination since some, like circle are self terminating.
(command "circle" cen cir) where cen is the centre of the circle and cir is a point on the circumference.
You can try this out using some values at the command prompt to see how this works:
(command "circle" "100,100" "150,150")
Note: values in expressions must be enclosed in quotes whereas variable names are not.
The following code will draw a square using a polyline, specifying 4 points and then C to close:
(command "pline" "50,50" "50,70" "70,70" "70,50" "c")
Elements from a List
When you used (setq a (getpoint)) you assigned the X and Y coordinate numbers to variable a. That Variable now is a list that may look like (5 10). If you want to look at the list in variable a, AutoLISP gives you a convenient way to do that from the command line.
!a Placing the ! (exclamation mark character) in front of the variable will display the value or values of that variable.
Car (X co-ordinate or 1st element)
The primary command for taking a list apart, (car) gives you the first element of a list. If the value of variable a is the list (5 10), then:
(setq b (car a)) would assign to the variable b the value of the first element in a which is 5.
Cdr (second and remaining elements)
This is the secondary command for taking a list apart. (cdr) gives you the second and remaining elements of the list, in other words; everything after the first element. If the value of variable a is the list (2 5 7 9 11), then:
(setq b (cdr a)) would assign to variable b the second and remaining elements of the list in variable awhich is (5 7 9 11).
Cadr (Y co-ordinate or 2nd element)
This always produces the second element of a list. Assuming the value of variable a is the list (5 10), then:
(setq b (cadr a)) would give b the value 10.
Caddr (Z co-ordinate or 3rd element)
This always produces the third element of a list. Assuming the value of variable a is the list (3 7 5) then:
(setq c (caddr a)) would assign the value 5 to variable c.

Example Programs
Drawing things
This program draws a rectangle by pointing to two points
(defun c:retan (/ pl p2 p3 p4)(setq pl (getpoint "\nfirst corner of rectangle: "))(setq p3 (getcorner "\nsecond corner of rectangle: "))(setq p2 (list (car pl)(cadr p3)))(setq p4 (list (car p3)(cadr pl)))(command "line" pl p2 p3 p4 "c")(princ))
Converting data
(defun dtr (a)
(* pi (/ a 180)) )
(defun rtd (a)
(/ (* a 180) pi)
Things to strings
strcase (string case)
Changes a string of text from lower case to upper case, leaving upper case characters as they are. eg:
(strcase "Hello") returns "HELLO"
(strcase a) returns the alphabetic characters in variable a from lower case to upper case.
strcat (string cat)
Returns two or more separate strings as one. eg:
(strcat "H" "ello") returns "Hello"
(strcat a b) returns two strings in variable a & b as one.
strlen (string length)
Returns the length, of the characters of a string. eg:
(strlen "hello") returns 5.
(strlen a) returns the length of a string in variable a.
substr (substitute string)
Returns a part of a string, from a specified position, ending either at the end or another specified position. eg:
(substr "Hello 2) returns "ello".
(substr "Hello 2 1) returns "e".
(substr "Hello" 3 2) returns "ll"

List Manipulation
The apostrophe character, ' serves a special function in AutoLISP. For example, if a group of items is preceded by an apostrophe, it is treated as a list. eg:
'(20 10 5) is treated as a list.
Angle
Returns an angle between two points in radians. To use that angle in AutoCAD you have to convert it back to decimal degrees. eg: (setq a (angle pnt1 pnt2)) sets the angle between pnt1 and pnt2 to the variable a.
To use a:
(command "text" pnt1 "40" a t) The text command with a height of 40, rotation angle assigned to variable a and a text string to variable t. But a is not the correct rotation angle because it is in radians.
Append
Takes any number of specified lists and joins them together as one list. eg:
(append '(10 20) '(30 40)) returns the list: (10 20 30 40).
(append a b) returns the list in variable a and the list in variable b as one.
Distance
Measures the distance from two known points. eg:
(setq dist1 (distance pnt1 pnt2)) returns the distance between pnt1 and pnt2 and assigns the distance to a variable called dist1.
Length
Returns the number of elements in a list. eg:
(length '(a b c d)) returns 4.
Member
Looks for a match and returns that and the rest of the list eg:
(member 'c '(a b c d e)) returns (c d e).
Nth
Returns the nth element in a list, where n is the number of the element to return. (Zero is the first element). eg:
(nth 3 '(a b c d)) returns d.
Assoc (associative)
Often used with the (subst) function; the (assoc) function lets you search for a specific element, then assign that element to a variable.
Lets assume variable b is the list ((10 5.5 2.7)(40 5)) and you are looking for a value 40. You want to pull out the entire element and assign it to a variable c. eg:
(setq c (assoc 40 b))
This assigns the entire element containing the 40 in the list b to variable c. Now c is a list that looks like this: (40 5).
Subst (subsitute)
Allows you to substitute one aspect for another. When substituting ALWAYS substitute the new item for the old in the list. Now lets substitute 20 for the 5 in the variable c.
(setq b1 (subst '(40 20) c b))
Now b1 is the new list.
'(40 20) is the new element substituted for the old element (40 5) c, found in list b.
If you want to use a variable which represents the value…
(setq bl (subst '(40 h) c b)) … looks like it should work, but it does not. The new element will look like this: (40 h).
(subst) cannot interpret variables. You need to construct a new variable containing the entire list element, then use the new variable in the (subst) function.
Cons (construct)
Constructs a new list with the new element placed at the begining. Assume variable c contains the following list: (40 5). Also, assume variable h contains the real number 20.0 then:
(setq d (cons (car c) h)) Remember, (car c) gives you 40. Therefore, (car c) is the new first element, followed by the value of h. Thus it produces a new list d (40 20.0).
Now we substitute:
(setq b1 (subst d c b)) That substitutes the new element found in variable d for the old element found in variable c. (In the list found in variable b) and assigns the new list to b1.

Conversions
Angtos (angle to string)
Takes an angle in radians and converts it into a string, using a specific format. Angtos has two arguments, the first controls the format and the second controls the precision.
Assuming variable a has an angle in radians. eg:
(angtos a 0 4) returns "180.0000" where 0 is the format (degrees) and 4 is the precision, in this case, 4 decimal places.(angtos a 0 0) returns "180"(angtos a 1 4) returns "180d0"0""
Fix
This function returns the convertion of a real number to an integer and drops the remainder. eg:
(fix 8) returns 8(fix 8.6) returns 8
Float
This function returns the convertion of an integer to a real number. (One can use either real or an integer.) eg:
(float 8) returns 8.0000(float 8.6) returns 8.6000
Ascii
Returns the convertion of the first character of a string into its ASCII character code. (an integer) eg:
(ascii "a") returns 97(ascii "A") returns 65, upper and lower case characters have different ascii character codes.(ascii "BLUE") returns 66(ascii "BALL") returns 66, only the first character is evaluated.
Chr
Returns the convertion of an Integer representing an ASCII character code into a single character string. eg:
(chr 65) returns "A"(chr 66) returns "B"
Atof (ascii to float)
Returns the convertion of a string into a real number. eg:
(atof "9.3") returns 9.3000(atof "2") returns 2.0000
Rtos (real to string)
Returns the convertion of a real number to a string with a specified format.
Rtos Mode Format1Scientific2Decimal3Engineering (feet & decimal inches)4Architectural (feet & fractional inches)5Arbituary fractional units
The real number can be set according to mode and precision. eg:
(rtos 7.2 1 4) returns "7.200OE+00"(rtos 7.2 2 2) returns "7.20"
Itoa (integer to ascii)
Returns the convertion of an integer into a string. eg:
(itoa 25) returns "25"
Atoi (ascii to integer)
Returns the convention of a string into an integer. eg:
(atoi "25") returns 25

Conditionals
In AutoLisp, the equals character (=) is not an assignment function. In other words, it is not used to assign a value to a variable as it is in some other programming languages. AutoLisp uses the (setq) function to perform this task. In AutoLisp, the equals character is used to test if items are equal, it does not make them equal. This is very useful if we are trying to test certain conditions. For example, we can begin to construct tests with an outcome such as "if one thing is equal to another thing, do something". That's what conditionals are all about; they allow your program to make decisions.
If
(if) is the standard if-then-else statement. In AutoLISP you may only match one if statement with a then statement. eg:
(if (= a b) (setq b 5 (setq b 6))
If a is equal to b, then b will be assigned the value 5. If it is not, then b will be assigned the value 6.
Cond (conditional)
This function accepts any number of lists as arguments. It evaluates the first item in each list (in order supplied) until one of these items is a value other than nil. eg: A user's response string is variable s.
(cond  ((= s "Y") 1)  ((= s "y") 1)  ((= s "N") 0)  ((= s "n") 0)  (t nil))
This function tests the response and returns 1 if it is "Y" or "y", and 0 if it is "N" or "n", and nil otherwise.
Repeat
Similar to a loop but repeat will only go through the commands as many times as is told. eg:
(setq a 10)(setq b 100)(repeat 3  (setq a (+ a 10)))(setq b (+ b a)))
Returns 140.
While
Is another loop control command available in AutoLISP. A loop is necessary if you want to repeat a command. However, unless you have a way of controlling it, the program will run forever and hang you up. eg:
(setq a "w") Sets up the controlling variable to a value other than nil.(while a The loop will continue, begining with the commands that follow, until the variable a is set to nil.  (…some functions…) Are the functions that are performed in the loop.  (if (= c d) (setq a nil)) Evaluates if c is equal to d, and if so, sets the loop controlling variable a tonil to end the loop.) A closing parenthesis closes the loop, and program will continue with the commands after this.

Entities
An entity is the smallest object you can place on your screen. The following are entities: LINE, CIRCLE, ARC, TEXT, POLYLINES, etc. Entities are stored and referenced in the drawing database. They can be changed and manipulated using AutoLISP to suit your needs. Each entity has a massive definition in AutoCAD's database. eg: The data for a single line contains the following info:
Entity name, Entity type, Layer, Color, Beginning X Y coordinate, Ending X Y coordinate, Line type, etc. You can modify any of the above aspects. An example of an entity list:
( - 1 <Entity name: 60000014) (0 "CIRCLE") (8 . "LAYER1")
(10 . 50.000 100.000) (40 . 60.000)
It is an entity list of a circle on layer LAYER1, center point relative to 0,0 of 50.0,100.0 , and a radius of 60.0
Entsel and Ssget (select entities and selection sets)
Both give you a way of selecting the entities for the selection set. (entsel) only selects one entity at a time. You may not use WINDOW or CROSSING to select entities. (ssget) however lets use WINDOW or CROSSING as well as other selection techniques. You will mostly be using (ssget).
(setq a (ssget)) will prompt you to select objects. You have now created a selection set with a specific name, <Selection set:l> ,assigned to variable a, or use filter option (setq a (ssget "X" '((0 . "TEXT")))) to search database for certain entities or codes.
Ssname (get entity name)
Lets you secure the name of the entity. The name of the entity is realy a hexadecimal number, therefore don't expect to see a name like LINE, or CIRCLE etc. The name of your entity might be 60000018.
Lets assume variable a is the selection set and variable i is set to 0. (setq i 0) To set Counter variable. (setq na (ssname a i)). This assigns na the entity name found in the selection set a at index number i. Remember that a selection set may contain more than one entity name. You can point to each entity by using its relative number in the selection set. eg: Entity 1 is Index 0 , Entity 2 is Index 1 , etc.
Entget (get entity list)
This command actually pulls out, or extracts, the entity list. The entity list can be assigned to a variable. (setq b (entget na)) That assigns to b the entire entity list for that entity name.
Subst (substitute new for old)
Allows you to substitute one aspect for another. Assume variable b is the name of the list and variable ccontains the value of the element: (40 . 60.0000) (setq bl (subst '(40 . 30.0000) c b)) ;bl is now the new list. '(40 . 30.0000) is the new element substituted for the old element c found in list b.
Sslength
Gives you the length or number of selections made.
Entmod (entity modification)
Gives you the ability to take the newly modified entity list and write it back to the database to update the drawing. Now that you have a new list in the variable b1, you want to make bl the permanent list in your drawing database. (entmod bl) You should see the change appear on the screen.

More Examples
Change Cross Hair Angle
This program permits you to draw lines perpendicular to other lines. The program measures the angle of the line chosen, and shifts the SNAP ANGLE to the angle of that line. Use ORTHO ON and draw perpendicular to your chosen line.
(defun c:perpdon (/ a b pntl pnt2 angl) (graphscr)(setq a (entsel))(setq b (entget (car a)))(setq pntl (cdr (assoc 10 b)))(setq pnt2 (cdr (assoc 11 b)))(setq angl (angle pntl pnt2))(setvar "snapang" ang1)(princ))
(defun c:perpdoff (setvar "snapang" 0)(princ))
Erase Screen
Erases everything on the drawing screen. If you are in a ZOOM ALL position, the program erases everything within the limits of the drawing.
Note: if you accidentally invoke this command, you can recover with OOPS.
(defun c:erasescr (/ l u)(setq l (getvar "limmin"))(setq u (getvar "limmax"))(command "erase" "w" l u "")(princ))
Change Layer
Lets you select objects by any selection method and change their layer. The target layer is chosen by simply pointing to an object on the desired layer. All objects selected will then change to that target layer. To test this program, you will need to create a drawing with objects on different layers.
(defun c:chlayer (/ a1 a2 n index b1 b2 d1 d2 b3)(graphscr)(prompt "\nselect entities to be changed: ")(setq a1 (ssget))(prompt "\npoint to entity on target layer: ")(setq a2 (entsel))(setq n (sslength a1))(setq index 0)(setq b2 (entget (car a2)))(setq d2 (assoc 8 b2))(repeat n(setq b1 (entget (ssname a1 index)))(setq d1 (assoc 8 b1))(setq b3 (subst d2 d1 b1))(entmod b3)(setq index (+ index 1)))(princ))
Now let's examine the program line by line.
(defun c:chlayer (/ a1 a2 n index b1 b2 d1 d2 b3)
Defines the function with all local variables.
(graphscr)
Changes to graphics screen.
(prompt "\nSelect entities to be changed: ")
This is a prompt statement.
(setq a1 (ssget))
Allows you to select the objects to be changed. The selection set is assigned to variable al.
(prompt "\npoint to entity on target layer: ")
This is a prompt statement.
(setq a2 (entsel))
This is a special type of selection statement that allows you to select only one entity.
(setq n (sslength a1))
Measures the number of entities in the selection set in variable a1.
(setq index 0)
Sets the variable called index to 0.
(setq b2 (entget (car a2)))
This statement gets the entity list from a2. Thus, a2 is assigned the entity list.
(setq d2 (assoc 8 b2))
This looks for the code 8 in entity list a2, then assigns the sublist to d2.
(repeat n
This begins the loop that pages through the selection set.
(setq bl (entget (ssname a1 index)))
This gets the entity list and assigns it to b1.
(setq d1 (assoc 8 b1))
Gets the sublist code 8 (the layer).
(setq b3 (subst d2 d1 b1))
Substitutes the new d2 layer for the old d1 layer in the entity list a1, and assigns it to the new entity list b3.
(entmod b3)
Updates the new entity list in the database.
(setq index (+ index 1))
Increases the index variable by 1, making it ready for the next loop. The first ) closes the repeat loop. (princ) exits quietly. The second ) closes the function.
Substitute text
This program lets you choose a line of text and substitute another line at exactly the same place.
(defun c:subtext (/ a b d e d1 b1 y)(prompt "\nSelect text line: ")(setq a (entsel))(setq b (entget (car a)))(setq d (assoc 1 b))(prompt (cdr d))(terpri)(setq e (getstring 1))(setq d1 (cons (car d) e))(setq b1 (subst d1 d b))(entmod b1)(setq y (getstring "\nIs this correct - Y : "))(if (= (srtcase y) "N") (entmod b))(princ))
Text - Own Distance, Own Height
This program lets you change the distance between multiple text lines. In addition to the standard start point and height, you are asked to enter the distance between text lines. You may enter as many text lines as you wish. To stop the program, enter an asterix (*).
(defun tex (/ p1 a b c d e f)(setq pl (getpoint "\nStarting point: "))(setq a (getdist p1 "\nEnter height: "))(setq c (getdist p1 "\nline spacing: "))(setq d "T")(while d(setq e (getstring 1 "Text: "))(command "text" pl a "0" e)(setq pl (list (car p1)(- (cadr p1) c)))(setq f (getstring))(if (= f "*")(setq d nil)))(princ))
Global Text Height Change
This program allows you to globally change the size of text within a WINDOW or CROSSING without affecting other entities.
(defun chtext (/ a ts n index b1 b c d b2)(setq a (ssget))(setq ts (getreal "\nEnter new text size"))(setq n (sslength a))(setq index 0)(repeat n(setq b1 (entget (ssname a index)))(setq index (1+ index))(setq b (assoc 0 b1))(if (= "TEXT" (cdr b))(progn(setq c (assoc 40 b1))(setq d (cons (car c) ts))(setq b2 (subst d c b1))(entmod b2))))(princ))

转载于:https://www.cnblogs.com/DeeLMind/p/7742360.html
展开全文
weixin_30322405 2017-10-27 11:31:00
• 由于Autolisp是小众语言，博客的代码插件并不支持Autolisp语法着色。但博客支持html语法。 原理：将着色效果转化为html 代码，效果如下： ;;------------------=={ Get Files Dialog }==------------------;; ;; ...

由于Autolisp是小众语言，博客的代码插件并不支持Autolisp语法着色。但博客支持html语法。
原理：将着色效果转化为html 代码，效果如下：
;;------------------=={ Get Files Dialog }==------------------;;

;;                                                            ;;

;;  An analog of the 'getfiled' function for multiple files.  ;;

;;------------------------------------------------------------;;

;;  Author: Lee Mac, Copyright 2013 - www.lee-mac.com       ;;

;;------------------------------------------------------------;;

(
defun
LM:getfiles
(
msg def ext
/
*error*
dch dcl des dir dirdata lst rtn
)

(
defun
*error*
(
msg
)

(
if
(
=
'file
(
type
des
))

(
close
des
)

)

(
if
(
and
(
=
'int
(
type
dch
))
(
<
0
dch
))

(
dch
)

)

(
if
(
and
(
=
'str
(
type
dcl
))
(
findfile
dcl
))

(
vl-file-delete
dcl
)

)

(
if
(
and
msg
(
not
(
wcmatch
(
strcase
msg
t
)
"*
break
,*cancel*,*exit*"
)))

(
princ
(
strcat
"\nError: "
msg
))

)

(
princ
)

)
................

实现方法之一：使用Everedit设置好代码的着色效果，并复制为Rtf格式，使用Word另存为Html 文件；或者使用rtf2html的工具软件。

实现方法之二：有高手（见过好几个版本的）使用autolisp语言编写了将lsp代码转化为html文件的源文件。

本人推荐：方法一。

转载于:https://www.cnblogs.com/InspiringMind/p/4659452.html
展开全文
P88888888899999 2019-10-01 15:07:44
• qq_37466069 2019-08-14 16:01:01
• haut_ykc 2020-02-21 13:03:14
• weixin_43750513 2020-07-30 17:15:01
• ## 其实你已经在使用Lisp语法了 lisp unix

spidercoco 2014-05-23 09:08:09
• ## 736 Lisp 语法解析（括号嵌套-递归） 算法

qq_39445165 2021-09-05 15:01:59
• ## 关于Editplus编辑Lisp语法高亮的问题 lisp

msnlogo 2015-02-07 10:23:46
• ## LeetCode题解(0736)：Lisp语法表达式解析(Python) leetcode python 字符串

Changxing_J 2020-08-18 09:21:04
• umbrellasoft 2019-06-09 04:35:02
• qq_37168218 2020-03-12 13:02:29
• wild46cat 2017-10-07 17:21:09
• DreamPixel 2013-07-12 11:36:34
• qq_35649707 2020-07-28 23:46:08
• 4星
1.93MB renming7050201 2008-01-11 16:14:04
• ## 初识LISP（1）——基本的结构、语法与数据类型 LISP 结构 数据类型

studyhard232 2017-04-07 21:37:42

...